radius-project / radius-project/dashboard
parseResourceId rejects legal resource names and types, and ResourceLink throws when it does
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 18
- Forks
- 13
- Avg merge
- 1d 12h
- Merged PRs (30d)
- 10
Description
Steps to reproduce
- Deploy a resource whose name contains an underscore or a dot, for example
my_apporfrontend.v2, or whose resource type contains a digit, for exampleApplications.Datastores/sqlDatabases2. - Open the dashboard and navigate to any list that renders that resource — Resources, Applications, or Environments.
Observed behavior
The row does not render. ResourceLink throws and the failure propagates to the surrounding error boundary rather than degrading gracefully.
The cause is the regular expression in packages/rad-components/src/resourceId.ts:
const RESOURCE_ID_REGEX =
/^\/planes\/radius\/(?<plane>[0-9a-zA-Z-]+)\/resourceGroups\/(?<group>[0-9a-zA-Z-]+)\/providers\/(?<namespace>[a-zA-Z\\.]+)\/(?<type>[a-zA-Z]+)\/(?<name>[0-9a-zA-Z-]+)$/i;
Three character classes are narrower than the identifiers Radius actually accepts:
nameis[0-9a-zA-Z-]+, so.and_are rejected.typeis[a-zA-Z]+, so a type containing a digit is rejected.planeandgroupare also digit-and-hyphen only, so an underscore in a resource group is rejected.
parseResourceId then returns undefined, and plugins/plugin-radius/src/components/resourcelink/ResourceLink.tsx turns that into a thrown error:
const parsed = parseResourceId(props.id);
if (!parsed) {
throw new Error(`Invalid resource id ${props.id}`);
}
Because parseResourceId is the single shared parser — all eleven consumers import it from @radapp.io/rad-components — the same input also silently drops the breadcrumb, the graph node label, and the resource-group column elsewhere.
There is a separate latent defect in the same expression: the namespace class is written [a-zA-Z\\.]+, which inside a regex literal is an escaped backslash plus a dot. It therefore accepts a literal \ in a namespace, which is not valid in a resource id.
Desired behavior
parseResourceId should accept every identifier the Radius control plane accepts, and the character classes should be derived from the documented naming rules rather than guessed.
Separately, ResourceLink should not throw on an id it cannot parse. An unparseable id is a data condition, not a programming error, and rendering plain text instead of a link would degrade a single cell rather than an entire view.
Workaround
Avoid . and _ in resource names and resource group names.
Additional context
Two KNOWN-DEFECT characterization cases pinning the current behavior are in packages/rad-components/src/__test__/resourceId.test.ts, added in nicolejms/dashboard#1. They assert that these inputs are rejected today, so they will fail and need updating when this is fixed — that is intentional, and the expected-change is the signal that the fix landed.
Found while building out test coverage ahead of the graph and plugin rearchitecture work, tracked in docs/design/2026-09-dashboard-plugin-test-plan.md.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with packages/rad-components/src/resourceId.ts and packages/rad-components/src/test/resourceId.test.ts, then inspect plugins/plugin-radius/src/components/resourcelink/ResourceLink.tsx. Use the documented Radius naming rules to verify accepted identifiers and update the characterization cases. Done means legal names parse correctly and an unparseable id renders as plain text without throwing.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- frontend
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 76/100