{"record":{"id":"8feb22a49ab803bf","repo":"elsa-workflows/elsa-core","slug":"value-is-not-a-well-formed-permission-expected-resource-verb","errorCode":null,"errorMessage":"'{value}' is not a well-formed permission. Expected '{resource}:{verb}'.","messagePattern":"'(.+?)' is not a well-formed permission\\. Expected '(.+?):(.+?)'\\.","errorType":"exception","errorClass":"FormatException","httpStatus":null,"severity":"error","filePath":"src/common/Elsa.Api.Common/Authorization/Permission.cs","lineNumber":111,"sourceCode":"\n        var separator = trimmed.IndexOf(Separator);\n\n        if (separator <= 0 || separator == trimmed.Length - 1)\n            return false;\n\n        var resource = trimmed[..separator];\n        var verb = trimmed[(separator + 1)..];\n\n        if (verb.IndexOf(Separator) >= 0 || verb.IndexOf(PathSeparator) >= 0)\n            return false;\n\n        permission = new(resource, verb);\n        return true;\n    }\n\n    /// <summary>Parses <paramref name=\"value\"/>, throwing when it is not a well-formed permission.</summary>\n    public static Permission Parse(string value) =>\n        TryParse(value, out var permission) ? permission : throw new FormatException($\"'{value}' is not a well-formed permission. Expected '{{resource}}:{{verb}}'.\");\n\n    /// <inheritdoc />\n    public override string ToString() => $\"{Resource}{Separator}{Verb}\";\n}\n","sourceCodeStart":93,"sourceCodeEnd":116,"githubUrl":"https://github.com/elsa-workflows/elsa-core/blob/fe9217bdfa0e27f0e09e45006eb6898f616e513d/src/common/Elsa.Api.Common/Authorization/Permission.cs#L93-L116","documentation":"Thrown by Permission.Parse (a validation guard wrapping TryParse) when the input string does not match the strict 'resource:verb' shape: empty or whitespace input, a missing separator, an empty resource or verb, or a second separator or path separator inside the verb all fail TryParse and cause Parse to throw. Use TryParse when malformed input is expected.","triggerScenarios":"Calling Permission.Parse with strings like 'read', ':read', 'resource:', 'a:b:c', or containing whitespace/invalid characters.","commonSituations":"Hardcoded permission strings after renaming a resource or verb; configuration/claims carrying concatenated permission lists split incorrectly.","solutions":["Use Permission.TryParse and handle the false case instead of Parse","Correct the string to 'resource:verb' form","Split multi-permission strings correctly before parsing each element"],"exampleFix":"// before\nvar p = Permission.Parse(\"can-read\");\n// after\nif (!Permission.TryParse(\"can-read\", out var p))\n    logger.LogWarning(\"Invalid permission: {P}\", \"can-read\");","handlingStrategy":"validation","validationCode":"if (!value.Contains(':')) throw new FormatException($\"Permission '{value}' must be 'resource:verb'\");\nvar parts = value.Split(':');\nif (parts.Length != 2 || parts.Any(string.IsNullOrWhiteSpace)) throw new FormatException($\"Invalid permission '{value}'\");","typeGuard":null,"tryCatchPattern":"try { var p = Permission.Parse(value); } catch (FormatException e) { logger.LogWarning(e, \"Bad permission\"); }","preventionTips":["Prefer TryParse over Parse for untrusted strings","Split multi-permission strings on the right separator before parsing","Centralize permission string constants to avoid typos"],"tags":["dotnet","authorization","format"],"backgroundTag":"invalid-argument-format","analyzedSha":"fe9217bdfa0e27f0e09e45006eb6898f616e513d","analyzedAt":"2026-09-13T20:32:34.702Z","contentChangedAt":"2026-09-13T20:32:34.702Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}