{"record":{"id":"e0b7b46c3de02b46","repo":"ory/kratos","slug":"invalid-start-after-format-q-expected-key-uuid","errorCode":null,"errorMessage":"invalid --start-after format %q: expected key=uuid (e.g. credentials=<id>)","messagePattern":"invalid --start-after format %q: expected key=uuid \\(e\\.g\\. credentials=<id>\\)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cmd/migrate/normalize_phone_handler.go","lineNumber":130,"sourceCode":"\tprintSummary(cmd, tables, allStats)\n\n\treturn nil\n}\n\ntype tableConfig struct {\n\tkey         string\n\tname        string\n\tselectQuery string\n\tupdateQuery string\n}\n\n// parseStartAfter parses --start-after flags of the form \"key=uuid\".\nfunc parseStartAfter(args []string) (map[string]uuid.UUID, error) {\n\tresult := make(map[string]uuid.UUID)\n\tfor _, arg := range args {\n\t\tkey, val, ok := strings.Cut(arg, \"=\")\n\t\tif !ok {\n\t\t\treturn nil, errors.Errorf(\"invalid --start-after format %q: expected key=uuid (e.g. credentials=<id>)\", arg)\n\t\t}\n\t\tid, err := uuid.FromString(val)\n\t\tif err != nil {\n\t\t\treturn nil, errors.Wrapf(err, \"invalid UUID in --start-after %q\", arg)\n\t\t}\n\t\tresult[key] = id\n\t}\n\treturn result, nil\n}\n\nfunc printSummary(cmd *cobra.Command, tables []tableConfig, allStats []normalizeStats) {\n\tout := cmd.OutOrStdout()\n\n\t_, _ = fmt.Fprintln(out)\n\n\ttw := tabwriter.NewWriter(out, 0, 0, 2, ' ', 0)\n\t_, _ = fmt.Fprintln(tw, \"\\tSCANNED\\tUPDATED\\tSKIPPED\\tERRORS\")\n","sourceCodeStart":112,"sourceCodeEnd":148,"githubUrl":"https://github.com/ory/kratos/blob/b86338da04a040247a07f46100a86dcfb3875909/cmd/migrate/normalize_phone_handler.go#L112-L148","documentation":"parseStartAfter parses --start-after flags expected in the form \"key=uuid\" (e.g. credentials=<id>). If an argument contains no '=' separator, strings.Cut fails and this error is returned, echoing the offending argument. It is a CLI argument format validation error, raised before any database work.","triggerScenarios":"Passing --start-after a value without '=' such as `--start-after credentials` or `--start-after 018f-...` instead of `--start-after credentials=<uuid>`.","commonSituations":"Copy-pasting only the UUID or only the key from a previous run's resume hint, shell quoting dropping the '=' (rare), or confusing this flag's format with other resume-style flags.","solutions":["Provide the value as key=uuid, e.g. --start-after credentials=018f3c2e-....","Quote the argument in shells where '=' or the value could be split.","Check `--help` for the exact expected format of --start-after."],"exampleFix":"// before\nkratos migrate normalize-phone --start-after 018f3c2e-3f4a-7b8c-9d0e-1f2a3b4c5d6e\n// after\nkratos migrate normalize-phone --start-after credentials=018f3c2e-3f4a-7b8c-9d0e-1f2a3b4c5d6e","handlingStrategy":"validation","validationCode":"for _, a := range startAfterFlags {\n    if !strings.Contains(a, \"=\") {\n        return fmt.Errorf(\"--start-after must be key=uuid, got %q\", a)\n    }\n}","typeGuard":"func validStartAfter(arg string) bool {\n    k, v, ok := strings.Cut(arg, \"=\")\n    _, err := uuid.Parse(v)\n    return ok && k != \"\" && err == nil\n}","tryCatchPattern":"null","preventionTips":["Copy the full key=uuid resume hint printed by a previous run verbatim","Quote flag values in shell scripts","Check --help output for flag format before scripting"],"tags":["cli","argument-parsing","flag-format"],"backgroundTag":"invalid-argument-format","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"}