feat: read a list resource's path parameters from its list block - #90
Merged
Conversation
A collection path like /orgs/{org}/… had nowhere to read org from: the
toolkit filled only the element schema, so emission refused the entity.
A list resource now declares the addressing its collection path requires
as the configuration of its list block, and reads it from req.Config.
The derivation reuses ensureParentParameters, which the resource and
datasource paths already call; every parameter is a parent, because a
collection path carries no item key. None carries RequiresReplace: a
list block declares a query, and a query has no plan to modify.
A failed path-parameter conversion now reports through the method it
lands in rather than assuming one: every lifecycle and invoke method
carries a resp with Diagnostics, and List carries a results stream.
schemaBuilder gains the list/schema package and the fact that it, like
the action package, declares no Computed.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
ShocOne
force-pushed
the
feat/list-resource-addressing-schema
branch
from
August 14, 2026 14:39
e11b602 to
5ad1d99
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The problem
A
list.ListResourcehas two schemas:ListResourceConfigSchemafor thelist {}block, and the resource schema for each result. The toolkit only everfilled the second. So a collection path like
/orgs/{org}/…had nowhere to readorgfrom, and emission refused the entity outright.derive.go:271,:405and:429all callensureParentParameters;listResourceat:440did not, andrender_listresource.go:77then hard-refusedany list call carrying path parameters.
What changed
ir.ListResource.AddressingSchema— the addressing attributes thecollection path requires, as a tree of their own. Built with the existing
ensureParentParameters. Every parameter is a parent, because a collectionpath carries no item key to absorb the last one.
RequiresReplaceis cleared:a list block declares a query, and a query has no plan for a modifier to act on.
render_listresource.go— builds config nodes through the existingjoinTree/addressingNamesmachinery, plans the call against them, and dropsthe refusal.
schemaBuildergains thelist/schemapackage andrendersComputed().Every
list/schemaattribute answersfalsefromIsComputed, so it degradeslike an action schema. The
schema.qualifier was hard-coded; it is nowsb.pkg().paramFailure— a failed path-parameter conversion reports through themethod it lands in rather than assuming one. Every lifecycle and invoke method
carries a
respwithDiagnostics;Listcarries a results stream and noresp, so the previously-hard-codedresp.Diagnostics.AddAttributeErrorwouldnot have compiled there.
listConfigModel,req.Config.GetinList,the query example supplies the required addressing, and the generated unit test
matches a parameterised path by pattern and stands a configuration up.
Measured effect
−140 refusals; +140 whole list resources.
The report diff is precisely what was predicted:
matches no scalar attribute and the entity has no id attributea list resource cannot supply path parametersthe element carries no scalar id attribute to publish as the list identityis string in the schema but int32 in the generated SDKAll 237 path-parameter list-resource refusals are gone. The 96 new ones are
those entities reaching emission for the first time and hitting their next
refusal — the #80 lesson, read the reasons rather than the total. The one new
type-mismatch is fixed by #88.
tfpfgen provider verifyreports no drift on all three;postcheck(
go mod tidy,go build,go vet) passes on all three.What I checked that is not green, and why it is not this PR
The generated providers' own unit tests fail, and they failed before this change.
Measured on
main,scratch/gen/github:That is a 100% failure rate before and after; this change adds no new failure
kind, only more instances of pre-existing ones.
postcheckdoes not rungo test, which is why it was never visible. Root causes so far: the mockresponse's content type (#89), and
internal/fixturessynthesisingtfpfgen-test-created-atinto adate-timefield — which needsformatcarriedinto the IR, work this tranche has not reached. The panics are
elements := result.GetEnvelope()on a nil payload, downstream of the same.I did not fold that in: it is repo-wide, multi-cause, and independent of this
change. It wants its own tranche.
Merge ordering
#88 touches
paramDeclarationin the same file. PerCLAUDE.mdboth were cutfresh from
mainrather than stacked, so whichever merges second needs a smallrebase there. Happy to do it on request.
Gates
gofmt -l internal cmd— emptyscripts/repo_hygiene_gate.sh— passgolangci-lint run— 0 issuesgo build ./... && go vet ./...— passgo test ./...— pass, coverage 91.3% totalNew toolkit tests:
internal/emit/render_listresource_test.go(4) andTestUnit_AddressingSchema_TakesEveryPathParameter.🤖 Generated with Claude Code