{"record":{"id":"567033e49e945350","repo":"Tencent/tinker","slug":"string-index-out-of-bound-perhaps-you-need-to","errorCode":null,"errorMessage":"string index out of bound: {}, perhaps you need to enable force jumbo mode.","messagePattern":"string index out of bound: (.+?), perhaps you need to enable force jumbo mode\\.","errorType":"exception","errorClass":"DexException","httpStatus":null,"severity":"error","filePath":"third-party/aosp-dexutils/src/main/java/com/tencent/tinker/android/dx/instruction/InstructionWriter.java","lineNumber":119,"sourceCode":"        currRegF = 0;\n        currRegG = 0;\n\n        InstructionCodec.encode(codeOut, this);\n    }\n\n    public void visitOneRegisterInsn(int currentAddress, int opcode, int index, int indexType, int target, long literal, int a) {\n        if (this.hasPromoter) {\n            target = this.insnPromoter.getPromotedAddress(target);\n        }\n\n        if (opcode == Opcodes.CONST_STRING) {\n            if (this.hasPromoter) {\n                if (index > 0xFFFF) {\n                    opcode = Opcodes.CONST_STRING_JUMBO;\n                }\n            } else {\n                if (index > 0xFFFF) {\n                    throw new DexException(\"string index out of bound: \" + Hex.u4(index)\n                            + \", perhaps you need to enable force jumbo mode.\");\n                }\n            }\n        }\n\n        currOpcode = opcode;\n        currIndex = index;\n        currTarget = target;\n        currLiteral = literal;\n        currRegisterCount = 1;\n        currRegA = a;\n        currRegB = 0;\n        currRegC = 0;\n        currRegD = 0;\n        currRegE = 0;\n        currRegF = 0;\n        currRegG = 0;\n","sourceCodeStart":101,"sourceCodeEnd":137,"githubUrl":"https://github.com/Tencent/tinker/blob/1b7ea02c239840f563ea64fb5bd286eb98d4011e/third-party/aosp-dexutils/src/main/java/com/tencent/tinker/android/dx/instruction/InstructionWriter.java#L101-L137","documentation":"Dex string indices are 16-bit for the const-string instruction, so an index above 0xFFFF cannot be encoded. InstructionWriter.visitOneRegisterInsn upgrades CONST_STRING to CONST_STRING/JUMBO automatically, but only when an InstructionPromoter is attached (this.hasPromoter); without one, an oversized index is rejected with this DexException. The message itself points at the remedy: enable force-jumbo mode.","triggerScenarios":"Writing a dex that references more than 65,536 strings while using InstructionWriter without a promoter attached, so a const-string whose string-id index exceeds 0xFFFF has no jumbo form to escape into.","commonSituations":"Apps with enormous string tables (generated code, many resources/R strings, big native-binding layers) exceeding the 64K string-id limit; building or patching such a dex through tinker's dex writer with jumbo promotion disabled; switching a build from dx/legacy jumbo-opcode mode to d8 without the equivalent setting.","solutions":["Enable force-jumbo mode so const-string is always emitted (or upgraded) to const-string/jumbo — in tinker's gradle config set `dexmode`/jumbo options (e.g. `tinkerPatch { buildConfig { ... } }` plus dx/d8 `--force-jumbo` in your build's dexOptions).","Attach an InstructionPromoter to the InstructionWriter (hasPromoter = true) so oversized indices are auto-upgraded to CONST_STRING_JUMBO instead of throwing.","Reduce the string count below 65,536 (strip unused generated strings, shrink resources, split dex via multidex) so plain 16-bit indices suffice."],"exampleFix":"// before: writer without promoter throws on index > 0xFFFF\nInstructionWriter writer = new InstructionWriter(dexBuffer);\nwriter.visitOneRegisterInsn(addr, Opcodes.CONST_STRING, stringIdx, ...);\n\n// after: attach the promoter so const-string is upgraded to const-string/jumbo\nInstructionPromoter promoter = new InstructionPromoter(dexBuffer);\nInstructionWriter writer = new InstructionWriter(dexBuffer, promoter);\nwriter.visitOneRegisterInsn(addr, Opcodes.CONST_STRING, stringIdx, ...);","handlingStrategy":"validation","validationCode":"// Pre-check the string table size before writing instructions\nboolean needsJumbo(com.tencent.tinker.android.dex.Dex dex) {\n    return dex.tableOfContents.stringIds.size > 0x10000;\n}\n// if needsJumbo(dex) is true, attach an InstructionPromoter or force-jumbo in the build","typeGuard":null,"tryCatchPattern":"try {\n    writer.visitOneRegisterInsn(addr, opcode, index, ...);\n} catch (com.tencent.tinker.android.dex.DexException e) {\n    if (e.getMessage() != null && e.getMessage().contains(\"jumbo\")) {\n        throw new IllegalStateException(\"string table exceeds 64K; enable force jumbo mode in the build config\", e);\n    }\n    throw e;\n}","preventionTips":["Enable force-jumbo (--force-jumbo / jumboEnabled) in builds whose string tables may exceed 65,536.","Attach an InstructionPromoter whenever you rewrite dex instructions with large string indices.","Track string-id count during dex construction and fail the build early once it crosses 0xFFFF."],"tags":["dex","string-index","jumbo-opcode","tinker"],"backgroundTag":null,"analyzedSha":"1b7ea02c239840f563ea64fb5bd286eb98d4011e","analyzedAt":"2026-08-14T15:16:52.110Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}