Skip to content

fix(lint): reject non-MemberExpression colinear under resolvedType#50

Merged
monga-puneet merged 2 commits into
mainfrom
pm/lint-resolved-type-non-member
Jun 5, 2026
Merged

fix(lint): reject non-MemberExpression colinear under resolvedType#50
monga-puneet merged 2 commits into
mainfrom
pm/lint-resolved-type-non-member

Conversation

@monga-puneet

Copy link
Copy Markdown
Contributor

Summary

A reasoning action whose colinear value is a bare identifier, string literal, ellipsis, or lone @namespace silently bypassed the resolvedType('invocationTarget') check. The compiler then fell back to target = name, producing a tool that reaches Preview / Agentforce runtime but resolves to no implementation when invoked. Customers saw a clean editor and broken behavior in Preview, with no signal pointing them at the typo.

reasoning:
    actions:
        capture_email: @utils.setVariables   # OK
            with email=...
        hello: world      # silently accepted today; reaches Preview as a no-op tool

This PR extends the constraint validator at packages/language/src/lint/constraint-validation.ts so any non-MemberExpression colinear under a resolvedType constraint emits a constraint-resolved-type Error pointing the author at the expected @namespace.member shape. The fix participates in the existing validatedRefs side channel so undefined-reference does not double-report.

Adds four colocated tests (bare identifier, string literal, ellipsis, lone @utils) to the existing resolvedType constraint describe block.

Test plan

  • New unit tests pass; the four pre-existing resolvedType constraint happy-path tests stay green.
  • pnpm --filter @agentscript/agentscript-dialect test — 1108/1108.
  • pnpm --filter @agentscript/language test — 170/170.
  • pnpm --filter @agentscript/agentforce test — 300/300.
  • pnpm --filter @agentscript/agentforce-dialect test — 282/282.
  • pnpm --filter @agentscript/agentfabric-dialect test — 54/54.
  • pnpm --filter @agentscript/compiler test — 801/801.
  • Web editor (Monaco) shows red squiggles + Issues panel 2 0 on the bare-identifier repro; hover text reads 'value' must be an @namespace.member invocation target (e.g. @actions.X). Got Identifier.
  • Hand-rolled compile harness reports two ERROR[constraint-resolved-type] diagnostics on the repro and zero false positives on @utils.setVariables / @actions.X / @subagent.X / @connected_subagent.X.

A reasoning action whose colinear value is a bare identifier, string
literal, ellipsis, or lone @namespace silently bypassed the
`resolvedType('invocationTarget')` check because the validator gated on
`node instanceof MemberExpression`. The compiler then fell back to
`target = name`, producing a tool that reaches Preview / Agentforce
runtime but resolves to no implementation when invoked.

Extend the constraint validator so any non-MemberExpression colinear
under a `resolvedType` constraint emits a `constraint-resolved-type`
Error pointing the author at the expected `@namespace.member` shape.
The fix participates in the existing `validatedRefs` side channel so
`undefined-reference` does not double-report.

Adds four colocated tests covering bare identifier, string literal,
ellipsis, and lone `@utils` cases in the existing
`resolvedType constraint` describe block.

@setu4993 setu4993 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good, see tiny request inline.

node,
lintDiagnostic(
range,
`'${fieldName}' must be an @namespace.member ${label} (e.g. @actions.X). Got ${kind}.`,

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can afford to be more explicit here about what is supported vs. not. I think @namespace is a bit too abstract.

Suggested change
`'${fieldName}' must be an @namespace.member ${label} (e.g. @actions.X). Got ${kind}.`,
`'${fieldName}' must be a member of @utils, @actions, @subagent or @connected_subagent. Got ${kind}.`,

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Took the suggestion and went one step further so it stays correct across dialects: enumerate from ctx.invocationTargetNamespaces (drop aliases) plus @utils from globalScopes. agentscript now produces exactly your suggested list; agentforce/agentfabric produce their own correct lists.

Per review feedback, replace the abstract "@namespace.member" wording
with the concrete list of namespaces the active dialect accepts. Pull
from ctx.invocationTargetNamespaces, drop aliases, and include @utils
when the dialect ships it.

Output by dialect:
- agentscript:  @actions, @connected_subagent, @subagent, @utils
- agentforce:   @actions, @connected_subagent, @response_formats,
                @subagent, @topic, @utils
- agentfabric:  @actions
@monga-puneet monga-puneet merged commit 0af5b24 into main Jun 5, 2026
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants