{"record":{"id":"c61f0c8884d17345","repo":"Unity-Technologies/UnityCsReference","slug":"two-consecutive-assembly-names-found-last-one","errorCode":null,"errorMessage":"Two consecutive assembly names found; last one: '{line}'","messagePattern":"Two consecutive assembly names found; last one: '(.+?)'","errorType":"exception","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"Editor/Mono/Scripting/RestrictedApisValidation/RestrictedApisConfig.cs","lineNumber":133,"sourceCode":"        if (lineSpan.Length == 0)\n            return;\n\n        var commentIndex = lineSpan.IndexOf('#');\n        if (commentIndex != -1)\n            lineSpan = lineSpan[..commentIndex].Trim();\n\n        if (lineSpan.Length == 0)\n            return;\n\n        var token = NextToken(ref lineSpan, out var separatorIndex);\n        if (separatorIndex == -1)\n        {\n            if (token[0] != '@')\n                throw new Exception($\"Invalid configuration line: '{line}'\");\n\n            if (flags.Get(PerAssemblyConfigFlag))\n            {\n                throw new Exception($\"Two consecutive assembly names found; last one: '{line}'\");\n            }\n\n            // Per-assembly configuration\n            flags.Set(PerAssemblyConfigFlag, true);\n            var assemblyPath = token.Slice(1).ToString();\n            if (!_perAssemblyConfig.TryGetValue(assemblyPath, out var assemblySpecificConfigs))\n            {\n                assemblySpecificConfigs = new PerAssemblyConfig();\n                _perAssemblyConfig.Add(assemblyPath, assemblySpecificConfigs);\n            }\n\n            currentMembersConfig = assemblySpecificConfigs._restrictedMembersConfig;\n            currentTypesConfig = assemblySpecificConfigs._restrictedTypesConfig;\n            return;\n        }\n\n        if (token[0] != ':')\n        {","sourceCodeStart":115,"sourceCodeEnd":151,"githubUrl":"https://github.com/Unity-Technologies/UnityCsReference/blob/225b0fbdb57cc17d094e8056b71f8314aba56f73/Editor/Mono/Scripting/RestrictedApisValidation/RestrictedApisConfig.cs#L115-L151","documentation":"Thrown when two per-assembly directives appear back-to-back. An '@assembly' line sets the PerAssemblyConfigFlag; encountering another '@assembly' line before any rule clears it is treated as an error because no rules were applied to the previous assembly.","triggerScenarios":"Two consecutive '@Assembly' lines in RestrictedApis.txt with no intervening ':id | signature | severity' rule between them.","commonSituations":"Listing multiple assemblies intending to share rules, or forgetting to add rules under the first assembly header.","solutions":["Add at least one rule line between consecutive '@assembly' directives, or remove the empty assembly header.","Re-read the documented format: '@assembly' switches context, the next rules apply to that assembly."],"exampleFix":"// before\n@A.dll\n@B.dll\n:1 | Foo::Bar | error\n// after\n@A.dll\n:1 | Foo::Bar | error\n@B.dll\n:2 | Baz::Qux | error","handlingStrategy":"validation","validationCode":"// Reject two consecutive '@assembly' headers with no rule between them.\nbool pendingAssembly = false;\nforeach (var l in lines)\n{\n    var t = l.AsSpan().Trim();\n    if (t.Length == 0 || t[0] == '#') continue;\n    if (t.StartsWith(\"@\"))\n    {\n        if (pendingAssembly) throw new FormatException($\"No rules for previous assembly before: '{l}'\");\n        pendingAssembly = true;\n    }\n    else pendingAssembly = false;\n}","typeGuard":null,"tryCatchPattern":"try { config = RestrictedApisConfig.Load(path); }\ncatch (Exception ex) when (ex.Message.Contains(\"Two consecutive assembly names\"))\n{ /* add a rule under the first header or remove it */ }","preventionTips":["Always place at least one rule line directly under each '@assembly' header.","Review multi-assembly configs to confirm each header has rules."],"tags":["config","restricted-apis","validation","parsing"],"backgroundTag":null,"analyzedSha":"225b0fbdb57cc17d094e8056b71f8314aba56f73","analyzedAt":"2026-08-13T19:07:19.849Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}