{"record":{"id":"8e13ca037e88ca77","repo":"JuliusBrussee/caveman","slug":"native-pack-invalid-core-budget-or-instructions","errorCode":null,"errorMessage":"native pack: invalid Core budget or instructions","messagePattern":"native pack: invalid Core budget or instructions","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"proxy/internal/nativepack/pack.go","lineNumber":96,"sourceCode":"\tfound := false\n\tfor _, skill := range pack.Skills {\n\t\tfor _, candidate := range skill.TaskTypes {\n\t\t\tif candidate == taskType {\n\t\t\t\tif !found || skill.Precedence > selected.Precedence {\n\t\t\t\t\tselected, found = skill, true\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\treturn selected, found\n}\n\nfunc validate(pack Pack) error {\n\tif pack.Schema != \"caveman.native-pack.v1\" || pack.ID == \"\" || pack.Version == \"\" || pack.Protocol < 1 {\n\t\treturn errors.New(\"native pack: invalid identity\")\n\t}\n\tif !pack.Core.Mandatory || pack.Core.Instructions == \"\" || pack.Core.EstimatedTokens > pack.Core.PromptTokenBudget {\n\t\treturn errors.New(\"native pack: invalid Core budget or instructions\")\n\t}\n\towners := map[string][]Skill{}\n\tids := map[string]bool{}\n\tfor _, skill := range pack.Skills {\n\t\tif skill.ID == \"\" || ids[skill.ID] || skill.Activation != \"classified\" || skill.Instructions == \"\" || len(skill.Instructions) > skill.PromptByteBudget {\n\t\t\treturn fmt.Errorf(\"native pack: invalid skill %q\", skill.ID)\n\t\t}\n\t\tids[skill.ID] = true\n\t\tfor _, taskType := range skill.TaskTypes {\n\t\t\towners[taskType] = append(owners[taskType], skill)\n\t\t}\n\t}\n\tfor _, skill := range pack.Skills {\n\t\tfor _, conflict := range skill.Conflicts {\n\t\t\tif !ids[conflict] {\n\t\t\t\treturn fmt.Errorf(\"native pack: %s conflicts with unknown skill %s\", skill.ID, conflict)\n\t\t\t}\n\t\t}","sourceCodeStart":78,"sourceCodeEnd":114,"githubUrl":"https://github.com/JuliusBrussee/caveman/blob/27d5a3981a347890211bb1bf2439e5c821a63bc9/proxy/internal/nativepack/pack.go#L78-L114","documentation":"The second identity check in nativepack.validate: the pack's Core section must be flagged Mandatory, must contain non-empty Instructions, and its EstimatedTokens must not exceed its PromptTokenBudget. This guarantees the always-injected core actually fits its budget before any skill is loaded.","triggerScenarios":"Loading a pack where core.mandatory is false or missing, core.instructions is empty, or core.estimated_tokens > core.prompt_token_budget (e.g. instructions grew past the declared budget after editing).","commonSituations":"Editing core instructions without re-measuring tokens; copying a pack template and forgetting the mandatory flag; budgets declared in a different unit (K vs raw tokens) than the estimator emits.","solutions":["Set core.mandatory = true and provide core.instructions text","Re-measure the instructions' token count and set estimated_tokens to that value, keeping it <= prompt_token_budget","If instructions are legitimately large, raise prompt_token_budget rather than under-reporting the estimate"],"exampleFix":"// before\npack.Core = nativepack.Core{Mandatory: false, Instructions: \"\", EstimatedTokens: 5000, PromptTokenBudget: 4000}\n\n// after\npack.Core = nativepack.Core{Mandatory: true, Instructions: coreText, EstimatedTokens: countTokens(coreText), PromptTokenBudget: 4000}","handlingStrategy":"validation","validationCode":"if !pack.Core.Mandatory || pack.Core.Instructions == \"\" || pack.Core.EstimatedTokens > pack.Core.PromptTokenBudget {\n    return errors.New(\"fix core section\")\n}\nerr := nativepack.Load(pack)","typeGuard":"func validCore(c nativepack.Core) bool {\n    return c.Mandatory && c.Instructions != \"\" && c.EstimatedTokens <= c.PromptTokenBudget\n}","tryCatchPattern":null,"preventionTips":["Compute estimated_tokens from the actual instructions text, never hard-code","Re-measure whenever core instructions change"],"tags":["nativepack","go","validation","budget","prompt-tokens"],"backgroundTag":null,"analyzedSha":"27d5a3981a347890211bb1bf2439e5c821a63bc9","analyzedAt":"2026-08-15T09:26:11.751Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}