{"record":{"id":"9ae83d1e42497b38","repo":"oracle/graal","slug":"unknown-field","errorCode":null,"errorMessage":"Unknown field ","messagePattern":"Unknown field ","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"error","filePath":"compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/replaycomp/BinaryReplayCodec.java","lineNumber":905,"sourceCode":"            case STACK_TRACE_ELEMENT_TAG ->\n                new StackTraceElement(readStringReference(in, state), readStringReference(in, state),\n                                readStringReference(in, state), requireNonNullString(readStringReference(in, state), \"stack trace holder\"),\n                                requireNonNullString(readStringReference(in, state), \"stack trace method\"), readStringReference(in, state), in.readPackedSignedInt());\n            case REGISTER_TAG -> findRegister(state.registerArchitecture(), in.readPackedUnsignedInt());\n            case FIELD_TAG -> {\n                Class<?> holder = ReplayTypeSupport.classCast(ReplayTypeSupport.decodeClass(requireNonNullString(readStringReference(in, state), \"field holder\")));\n                String name = requireNonNullString(readStringReference(in, state), \"field name\");\n                try {\n                    if (holder == String.class) {\n                        if (\"coder\".equals(name)) {\n                            yield String.class.getDeclaredField(\"coder\");\n                        } else if (\"value\".equals(name)) {\n                            yield String.class.getDeclaredField(\"value\");\n                        }\n                    }\n                    yield holder.getDeclaredField(name);\n                } catch (NoSuchFieldException e) {\n                    throw new IOException(\"Unknown field \" + holder.getName() + \".\" + name, e);\n                }\n            }\n            case ASSUMPTION_RESULT_TAG -> {\n                Object result = readValue(in, state);\n                int length = in.readPackedUnsignedInt();\n                Assumptions.Assumption[] assumptions = new Assumptions.Assumption[length];\n                for (int i = 0; i < length; i++) {\n                    assumptions[i] = (Assumptions.Assumption) readValue(in, state);\n                }\n                yield new Assumptions.AssumptionResult<>(result, assumptions);\n            }\n            case ASSUMPTION_TAG -> switch (in.readPackedUnsignedInt()) {\n                case ASSUMPTION_NO_FINALIZABLE_SUBCLASS ->\n                    new Assumptions.NoFinalizableSubclass((ResolvedJavaType) readValue(in, state));\n                case ASSUMPTION_CONCRETE_SUBTYPE -> {\n                    ResolvedJavaType subtype = (ResolvedJavaType) readValue(in, state);\n                    ResolvedJavaType context = (ResolvedJavaType) readValue(in, state);\n                    yield new DelayedDeserializationObject.ConcreteSubtypeWithDelayedDeserialization(context, subtype);","sourceCodeStart":887,"sourceCodeEnd":923,"githubUrl":"https://github.com/oracle/graal/blob/a66e9ccd1d7bf2552883939aa0788dfd0e294aab/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/replaycomp/BinaryReplayCodec.java#L887-L923","documentation":"Thrown when decoding a FIELD_TAG: the codec reflectively resolves a declared field by holder class and name (with special-casing for String.coder/value), and getDeclaredField throws NoSuchFieldException. The IOException 'Unknown field <holder>.<name>' means the field existed when the replay was recorded but not in the replaying JVM's classes.","triggerScenarios":"Replaying against a JDK/compiler build where the field was renamed, removed, or moved to a superclass; the stream is corrupt so the field-name string decodes to garbage.","commonSituations":"JDK version differences (e.g. String internals changing across JDK releases); replaying files recorded on a GraalVM development build carrying renamed fields; classpath shadowing loading an older class version.","solutions":["Re-record the replay file on the same JDK + GraalVM build used for replay","Verify the field exists: check holder.getDeclaredField(name) in the replaying environment","If the field genuinely moved, add a resolution case in the FIELD_TAG branch (as done for String 'coder'/'value')"],"exampleFix":"// before\nyield holder.getDeclaredField(name); // NoSuchFieldException -> IOException: Unknown field\n\n// after\n// special-case relocated fields, mirroring the String handling\nif (holder == SomeClass.class && \"oldName\".equals(name)) {\n    yield SomeClass.class.getDeclaredField(\"newName\");\n}\nyield holder.getDeclaredField(name);","handlingStrategy":"validation","validationCode":"static boolean fieldResolvable(Class<?> holder, String name) {\n    try { holder.getDeclaredField(name); return true; }\n    catch (NoSuchFieldException e) { return false; }\n}","typeGuard":null,"tryCatchPattern":"try {\n    result = codec.readReplay(in);\n} catch (IOException e) {\n    if (e.getMessage() != null && e.getMessage().startsWith(\"Unknown field\")) {\n        // JDK/class version skew: re-record on this JDK\n    } else throw e;\n}","preventionTips":["Replay with the same JDK version that recorded the file","When renaming a recorded field, add a compatibility case in the FIELD_TAG branch like the String coder/value handling"],"tags":["graalvm","replay-compilation","reflection","jdk-skew","deserialization"],"backgroundTag":null,"analyzedSha":"a66e9ccd1d7bf2552883939aa0788dfd0e294aab","analyzedAt":"2026-08-14T13:58:47.161Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}