{"record":{"id":"edfd79f9e8bc68e2","repo":"ory/kratos","slug":"err","errorCode":null,"errorMessage":"err","messagePattern":"err","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"selfservice/hook/error.go","lineNumber":49,"sourceCode":"\t_ login.PreHookExecutor  = new(Error)\n\n\t_ settings.PostHookPostPersistExecutor = new(Error)\n\t_ settings.PostHookPrePersistExecutor  = new(Error)\n\t_ settings.PreHookExecutor             = new(Error)\n\n\t_ verification.PreHookExecutor = new(Error)\n\t_ recovery.PreHookExecutor     = new(Error)\n)\n\ntype Error struct {\n\tConfig json.RawMessage\n}\n\nfunc (e Error) err(path string, abort error) error {\n\tswitch gjson.GetBytes(e.Config, path).String() {\n\tcase \"err\":\n\t\treturn errors.New(\"err\")\n\tcase \"abort\":\n\t\treturn abort\n\t}\n\treturn nil\n}\n\nfunc (e Error) ExecuteSettingsPreHook(w http.ResponseWriter, r *http.Request, _ settings.PreHookExecutorParams) error {\n\treturn e.err(\"ExecuteSettingsPreHook\", settings.ErrHookAbortFlow)\n}\n\nfunc (e Error) ExecuteSettingsPrePersistHook(w http.ResponseWriter, r *http.Request, _ settings.PostHookPrePersistExecutorParams) error {\n\treturn e.err(\"ExecuteSettingsPrePersistHook\", settings.ErrHookAbortFlow)\n}\n\nfunc (e Error) ExecuteSettingsPostPersistHook(w http.ResponseWriter, r *http.Request, _ settings.PostHookPostPersistExecutorParams) error {\n\treturn e.err(\"ExecuteSettingsPostPersistHook\", settings.ErrHookAbortFlow)\n}\n\nfunc (e Error) ExecuteLoginPostHook(w http.ResponseWriter, r *http.Request, g node.UiNodeGroup, a *login.Flow, s *session.Session) error {","sourceCodeStart":31,"sourceCodeEnd":67,"githubUrl":"https://github.com/ory/kratos/blob/b86338da04a040247a07f46100a86dcfb3875909/selfservice/hook/error.go#L31-L67","documentation":"This is the sentinel error of Ory Kratos' test `Error` hook (selfservice/hook/error.go:45-53). The hook reads its JSON config at the key matching the executed hook method (e.g. \"ExecuteSettingsPreHook\") via gjson; when the value is the string \"err\", `err()` deliberately returns `errors.New(\"err\")` so the flow execution fails. It exists purely to simulate hook failures in integration/e2e tests of flow error handling. Error 110 is the message surfaced through all the Execute* hook wrappers that call `err()`.","triggerScenarios":"Registering the `error` hook (hook.Error) in a flow's hook list with a JSON config like {\"ExecuteSettingsPreHook\":\"err\"} (or any other Execute* key set to \"err\"), then running that flow (login, registration, settings, recovery, verification) so the executor invokes the corresponding hook.","commonSituations":"Developers copy-pasting the `error` hook from Kratos test fixtures into real configuration (selfservice.flows.*.after/pre hooks); leftover test-only config promoted to production; contributing to Kratos and running e2e tests that intentionally fail a flow stage.","solutions":["Remove the `error` (hook.Error) hook from the affected flow in your Kratos config (selfservice.flows.<flow>.before/after.<method>.hooks) — it is a test-only hook.","If you want the flow to abort with a proper flow error instead, change the config value from \"err\" to \"abort\", which returns the flow's ErrHookAbortFlow rather than errors.New(\"err\").","Remove the offending key/value (e.g. \"ExecuteSettingsPreHook\":\"err\") from the hook's JSON config; `err()` then returns nil and the hook becomes a no-op."],"exampleFix":"// before (kratos.yml)\nhooks:\n  - hook: error\n    config:\n      ExecuteSettingsPreHook: \"err\"\n// after\nhooks:\n  - hook: require_verified_address  # or remove the hook entirely","handlingStrategy":"validation","validationCode":"// Before enabling the error hook, check what mode each configured key is in.\nfor key := range hookConfig {\n    v := gjson.GetBytes(rawCfg, key).String()\n    if v == \"err\" {\n        log.Fatalf(\"test hook %s configured with \\\"err\\\" - remove it from production config\", key)\n    }\n}","typeGuard":"func isErrorHookMode(cfg json.RawMessage, hookKey string) bool {\n    return gjson.GetBytes(cfg, hookKey).String() == \"err\"\n}","tryCatchPattern":"if err := flow.Execute(r); err != nil {\n    if err.Error() == \"err\" {\n        // deliberate failure injected by the test `error` hook;\n        // treat as config mistake, not a runtime fault\n        return fmt.Errorf(\"test error hook active: %w\", err)\n    }\n    return err\n}","preventionTips":["Never register the `hook: error` hook outside of test/e2e configuration files.","Grep kratos.yml / env-rendered config for 'hook: error' before deploying.","Prefer the \"abort\" mode (flow-specific ErrHookAbortFlow) over \"err\" when testing abort behavior, since it produces a meaningful flow error."],"tags":["ory-kratos","hooks","test-hook","config"],"backgroundTag":"invalid-config-value","analyzedSha":"b86338da04a040247a07f46100a86dcfb3875909","analyzedAt":"2026-09-07T15:58:15.934Z","contentChangedAt":"2026-09-07T15:58:15.934Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}