{"record":{"id":"e2126f151a4edda0","repo":"pulumi/pulumi","slug":"callback-not-found","errorCode":null,"errorMessage":"callback not found: ","messagePattern":"callback not found: ","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/pcl/runtime/interpreter.go","lineNumber":162,"sourceCode":"\tdefer s.functionsLock.Unlock()\n\ts.functions[uuidString] = fn\n\treturn &pulumirpc.Callback{\n\t\tToken:  uuidString,\n\t\tTarget: \"127.0.0.1:\" + strconv.Itoa(s.handle.Port),\n\t\t// PCL decodes strings containing non-UTF8 bytes losslessly, so the engine may send them to callbacks\n\t\t// hosted here.\n\t\tAcceptsByteString: true,\n\t}, nil\n}\n\nfunc (s *pclCallbackServer) Invoke(\n\tctx context.Context, req *pulumirpc.CallbackInvokeRequest,\n) (*pulumirpc.CallbackInvokeResponse, error) {\n\ts.functionsLock.RLock()\n\tfn, ok := s.functions[req.Token]\n\ts.functionsLock.RUnlock()\n\tif !ok {\n\t\treturn nil, errors.New(\"callback not found: \" + req.Token)\n\t}\n\tresp, err := fn(ctx, req.Request)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tb, err := proto.Marshal(resp)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"marshaling callback response: %w\", err)\n\t}\n\treturn &pulumirpc.CallbackInvokeResponse{Response: b}, nil\n}\n\nfunc (i *Interpreter) getCallbackServer() (*pclCallbackServer, error) {\n\ti.callbacksOnce.Do(func() {\n\t\ts, err := newPCLCallbackServer()\n\t\ti.callbacks = s\n\t\ti.callbacksErr = err\n\t})","sourceCodeStart":144,"sourceCodeEnd":180,"githubUrl":"https://github.com/pulumi/pulumi/blob/793f7b2e160db4321fb7fb6b0607461e01cb251e/pkg/pcl/runtime/interpreter.go#L144-L180","documentation":"The PCL interpreter hosts a local callback gRPC server (pclCallbackServer); callbacks are registered under a UUID token and the engine invokes them by token. If an Invoke request carries a token that has no registered function, the server returns \"callback not found: <token>\". This means the callback was never registered, or it was invoked after the interpreter/session ended.","triggerScenarios":"pclCallbackServer.Invoke (pkg/pcl/runtime/interpreter.go:162) looks up req.Token in s.functions and misses — e.g. the engine invokes a stale/expired callback token, or invokes a callback belonging to a different interpreter instance.","commonSituations":"Hook callbacks invoked after the program finished, retry of a failed operation reusing an old callback token, running multiple concurrent interpreters where tokens are sent to the wrong port, or cached state from a previous run being replayed.","solutions":["Re-run the program so hooks re-register fresh callback tokens; discard stale tokens from prior runs","Verify the callback Token/Target pair matches the interpreter instance currently serving","Avoid persisting or replaying callback tokens across deployments/runs","If concurrent, ensure each interpreter has its own callback server port and tokens are not mixed"],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"_, err := callbackClient.Invoke(ctx, req)\nif err != nil && strings.HasPrefix(err.Error(), \"callback not found\") {\n    // re-run the program to obtain fresh tokens; do not blindly retry with same token\n}","preventionTips":["Never reuse callback tokens from previous runs","Keep token and target port paired to the same interpreter instance","Register callbacks before any operation that can invoke them","Avoid replaying serialized engine state that embeds old tokens"],"tags":["pulumi","grpc","callback"],"backgroundTag":"unknown-callback-token","analyzedSha":"793f7b2e160db4321fb7fb6b0607461e01cb251e","analyzedAt":"2026-08-31T09:36:43.099Z","schemaVersion":2},"datasetVersion":"2026-09-01T08:17:40.651Z"}