radius-project / radius-project/dashboard

parseResourceId rejects legal resource names and types, and ResourceLink throws when it does

Open
#352 2 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

bug triaged
Dominant language
TypeScript
Stars
18
Forks
13
Avg merge
1d 12h
Merged PRs (30d)
10

Description

Steps to reproduce
  1. Deploy a resource whose name contains an underscore or a dot, for example my_app or frontend.v2, or whose resource type contains a digit, for example Applications.Datastores/sqlDatabases2.
  2. 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:

  • name is [0-9a-zA-Z-]+, so . and _ are rejected.
  • type is [a-zA-Z]+, so a type containing a digit is rejected.
  • plane and group are 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

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.