{"record":{"id":"12be676f24cdfb26","repo":"wavetermdev/waveterm","slug":"failed-to-read-secret-bindings-err-secret-w","errorCode":null,"errorMessage":"failed to read secret bindings (ERR-SECRET): %w","messagePattern":"failed to read secret bindings \\(ERR-SECRET\\): %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/buildercontroller/buildercontroller.go","lineNumber":312,"sourceCode":"\t\tbc.lock.Lock()\n\t\tif bc.process == process {\n\t\t\tbc.process = nil\n\t\t\texitCode := exitCodeFromWaitErr(process.WaitRtn)\n\t\t\tbc.setStatus_nolock(BuilderStatus_Stopped, 0, exitCode, \"\")\n\t\t}\n\t\tbc.lock.Unlock()\n\t}()\n}\n\nfunc (bc *BuilderController) runBuilderApp(ctx context.Context, appId string, appBinPath string, builderEnv map[string]string) (*BuilderProcess, error) {\n\tmanifest, err := waveappstore.ReadAppManifest(appId)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to read app manifest: %w\", err)\n\t}\n\n\tsecretBindings, err := waveappstore.ReadAppSecretBindings(appId)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to read secret bindings (ERR-SECRET): %w\", err)\n\t}\n\n\tsecretEnv, err := waveappstore.BuildAppSecretEnv(appId, manifest, secretBindings)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to build secret environment (ERR-SECRET): %w\", err)\n\t}\n\n\tif builderEnv == nil {\n\t\tbuilderEnv = make(map[string]string)\n\t}\n\tfor k, v := range secretEnv {\n\t\tbuilderEnv[k] = v\n\t}\n\n\tcmd := exec.Command(appBinPath)\n\tcmd.Env = append(os.Environ(), \"TSUNAMI_CLOSEONSTDIN=1\")\n\n\tif wavebase.IsDevMode() {","sourceCodeStart":294,"sourceCodeEnd":330,"githubUrl":"https://github.com/wavetermdev/waveterm/blob/a4447c1563b2df285ab89e76c82f91e1a1a49c1e/pkg/buildercontroller/buildercontroller.go#L294-L330","documentation":"After the manifest, runBuilderApp reads the app's secret bindings via waveappstore.ReadAppSecretBindings. This error (tagged ERR-SECRET) means the stored secret bindings file for the app could not be read or decrypted, so the app cannot be launched with its secrets.","triggerScenarios":"ReadAppSecretBindings fails — secrets file absent, corrupted, unreadable, or undecryptable (e.g. keychain/encryption key changed between sessions).","commonSituations":"User never provisioned secrets but the code path still requires reading bindings; OS keychain access denied; secrets store migrated between wave versions; encryption key rotated.","solutions":["Re-provision the app's secret bindings through the secrets UI/RPC","Check the secrets store file for corruption and restore or reset bindings","Verify the decryption key source (keychain) is accessible to the wave process","If the app needs no secrets, ensure bindings are stored as an empty set rather than missing"],"exampleFix":"// before\n// no bindings stored for app -> read fails\n// after\nwaveappstore.WriteAppSecretBindings(appId, map[string]string{}) // initialize empty bindings","handlingStrategy":"fallback","validationCode":"_, err := waveappstore.ReadAppSecretBindings(appId)\nif err != nil {\n    // initialize empty bindings so the read path succeeds\n    waveappstore.WriteAppSecretBindings(appId, map[string]string{})\n}","typeGuard":null,"tryCatchPattern":"if err := runApp(appId); err != nil {\n    if strings.Contains(err.Error(), \"ERR-SECRET\") && strings.Contains(err.Error(), \"secret bindings\") {\n        // re-provision secrets via secrets UI/RPC\n    }\n}","preventionTips":["Provision (even empty) bindings before first run","Test keychain access after OS upgrades","Avoid manual edits to the secrets store"],"tags":["go","secrets","security"],"backgroundTag":"secret-bindings-unavailable","analyzedSha":"a4447c1563b2df285ab89e76c82f91e1a1a49c1e","analyzedAt":"2026-09-01T15:26:23.972Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}