Summary
The hcl:merge:files:write (and related) actions fail at runtime when the consuming Backstage app forces Zod v4 via a Yarn resolution. The action handler is never reached — the error fires during Backstage's own input validation step.
Error
InputError: Invalid input passed to action hcl:merge:files:write, instance is not of a type(s) string
at NunjucksWorkflowRunner.executeStep (NunjucksWorkflowRunner.cjs.js:277:19)
Root cause
This package declares "zod": "^3.23.8" but has no local node_modules/zod, so it resolves to whatever the consuming app provides. When that is Zod v4 (released April 2025), the schema conversion breaks silently:
- Backstage's
parseSchemas() in @backstage/plugin-scaffolder-node only recognises two Zod v3 schema patterns (callback functions or key-value objects). A Zod v4 ZodObject matches neither, so parseSchemas() returns undefined for the input schema.
- However,
createTemplateAction still stores the raw Zod v4 object on action.schema.input.
- At runtime,
NunjucksWorkflowRunner sees action.schema.input is truthy and passes it to jsonschema.validate().
zod-to-json-schema doesn't recognise the v4 ZodObject shape and falls back to { "type": "string" }.
- The actual input (an object with
aSourcePath, bSourcePath, etc.) fails validation against { "type": "string" }.
Confirmed by running:
const zod = require('zod'); // v4.3.6
const zodToJsonSchema = require('zod-to-json-schema');
const schema = zod.z.object({ aSourcePath: zod.z.string(), outputPath: zod.z.string() });
console.log(zodToJsonSchema(schema)); // → { "type": "string" }
Versions
@seatgeek/backstage-plugin-scaffolder-backend-module-hcl: 2.0.1
zod (forced via Yarn resolution): 4.3.6
@backstage/plugin-scaffolder-node: ^0.4.10
Workaround
Pin a scoped Yarn resolution to force this package back to Zod v3:
"resolutions": {
"@seatgeek/backstage-plugin-scaffolder-backend-module-hcl/zod": "^3.23.8",
"zod": "^4.0.0"
}
Fix
Update the package to use Zod v4 (or declare a peer dependency on zod so consumers are warned of the incompatibility). The schema definitions themselves are straightforward and should be compatible with minor changes.
Summary
The
hcl:merge:files:write(and related) actions fail at runtime when the consuming Backstage app forces Zod v4 via a Yarn resolution. The action handler is never reached — the error fires during Backstage's own input validation step.Error
Root cause
This package declares
"zod": "^3.23.8"but has no localnode_modules/zod, so it resolves to whatever the consuming app provides. When that is Zod v4 (released April 2025), the schema conversion breaks silently:parseSchemas()in@backstage/plugin-scaffolder-nodeonly recognises two Zod v3 schema patterns (callback functions or key-value objects). A Zod v4ZodObjectmatches neither, soparseSchemas()returnsundefinedfor the input schema.createTemplateActionstill stores the raw Zod v4 object onaction.schema.input.NunjucksWorkflowRunnerseesaction.schema.inputis truthy and passes it tojsonschema.validate().zod-to-json-schemadoesn't recognise the v4ZodObjectshape and falls back to{ "type": "string" }.aSourcePath,bSourcePath, etc.) fails validation against{ "type": "string" }.Confirmed by running:
Versions
@seatgeek/backstage-plugin-scaffolder-backend-module-hcl:2.0.1zod(forced via Yarn resolution):4.3.6@backstage/plugin-scaffolder-node:^0.4.10Workaround
Pin a scoped Yarn resolution to force this package back to Zod v3:
Fix
Update the package to use Zod v4 (or declare a peer dependency on
zodso consumers are warned of the incompatibility). The schema definitions themselves are straightforward and should be compatible with minor changes.