smartcontractkit / smartcontractkit/cre-sdk-typescript
preHook makes every workflow fail with "Failed to parse configuration: Unexpected end of JSON input"
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 6
- Forks
- 9
- Avg merge
- 5h 23m
- Merged PRs (30d)
- 6
Description
Summary
Any workflow that supplies hooks.preHook fails to execute with an error that points at the config
file. The config is irrelevant — an empty hook on an otherwise-working workflow reproduces it.
✗ workflow execution failed: Failed to parse configuration: Unexpected end of JSON input
Reproduction
On the stock hello-confidential-workflows-ts scaffold, change only the handler registration:
cre.handler(
cronTrigger.trigger({ schedule: config.schedule }),
() => 'probe',
{ preHook: () => ({}) }, // remove this line and the same workflow runs
)
cre workflow simulate fast --target staging-settings
Root cause
RunnerBase.newRunnerHelper parses the config on every phase, before it dispatches on
request.request.case:
// packages/cre-sdk/src/sdk/wasm/runner.ts
static async newRunnerHelper(newRunner, configHandlerParams) {
hostBindings.versionV2()
const request = RunnerBase.getRequest()
const config = await configHandler(request, configHandlerParams) // includes the preHook phase
return newRunner(config, request)
}
and configHandler's default parser is JSON.parse(Buffer.from(request.config).toString()). The host
sends the preHook ExecuteRequest with an empty config, so this is JSON.parse('').
Either side can fix it: the host can populate config on preHook requests, or the SDK can skip config
parsing for that phase. Happy to open a PR for the SDK-side fix if that is the preferred direction —
I did not want to guess which of the two is intended.
What I ruled out
All of the following fail identically, so it is not the restriction contents, the TEE path, or my config:
- a fully-populated
RestrictionsJsonbuilt fromcre.restrictors.EVMRestrictor's own
limitCallContract/limitHeaderByNumber/limitWriteReporthelpers - with and without
maxTotalCalls typeset toCAPABILITY_RESTRICTION_TYPE_CLOSEDand to..._OPENcre.handlerInTeeand plaincre.handler--limits none- an empty hook returning
{}
The returned object typechecks against RestrictionsJson in every case.
Impact
The pre-execution capability budget is exactly the control a confidential workflow most wants, since
it bounds what a compromised handler can do. We had to ship ours as an exported, unit-tested function
that is not wired in, with a comment explaining why.
Secondly, and worth separating from the bug itself: the error message cost far more than the bug
did. "Failed to parse configuration" reads as your config file is malformed, so I spent over an
hour bisecting a valid config — deleting fields, shortening values, tuples versus arrays, measuring
byte sizes — and briefly concluded there was a config-size cliff. The reason that theory survived is
that a config which fails zod validation errors before the hook runs, so incomplete configs appear
to work and complete ones appear to break. Any error raised at hook-evaluation time, naming the hook,
would have made this a two-minute diagnosis.
Versions
@chainlink/cre-sdk1.20.0 (also reproduced on 1.18.0)creCLI v1.32.0 (cre updatereports it is the latest)- bun 1.4.2, Linux x64
- template
hello-confidential-workflows-ts
sdk/utils/config/index.js and sdk/wasm/runner.js are byte-identical between 1.18.0 and 1.20.0.
runner.ts was last touched in "Add prehook to the SDK" (2026-04-15), so this appears to have been
present since the feature landed.
Contributor guide
No contributing guide indexed for this repository
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/cre-sdk/src/sdk/wasm/runner.ts, especially RunnerBase.newRunnerHelper, and compare its phase dispatch with the default parser in sdk/utils/config/index.js. Reproduce with cre workflow simulate fast --target staging-settings using the hello-confidential-workflows-ts scaffold; done means a workflow with an empty preHook executes without the JSON parsing error.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript, wasm
- Domain
- backend
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 76/100