oracle/graal · error · ExperimentParserTypeError

Failed to parse experiment

Error message

Failed to parse experiment {experimentId} in {resource}: expected position to be an instance of Integer but got "{actualObject}"

What it means

While converting an optimization's position map, parseOptimization throws ExperimentParserTypeError when a position value is not a java.lang Integer — the optimization log encodes each inlining position as method-name -> bci, and every bci must be a JSON number that decodes to Integer. The error names the experiment, file, the 'position' property, the expected type and the offending object.

Solutions

  1. Regenerate the optimization log with the matching GraalVM/profdiff version instead of editing it by hand.
  2. If post-processing logs, keep bcis as unquoted JSON integers.
  3. Validate the file: every entry of each 'position' object must map a string method name to an integer.

Example fix

// before (log content)
{"name":"inlining","event":"...","position":{"m(int)":"7"}}
// after
{"name":"inlining","event":"...","position":{"m(int)":7}}
Defensive patterns

Strategy: validation

Validate before calling

// Validate a position object before handing the log to profdiff
Object pos = optimization.get("position");
if (pos instanceof Map<?,?> m) {
    for (Object v : m.values()) if (!(v instanceof Integer)) throw new IllegalArgumentException("Non-integer bci: " + v);
}

Type guard

static boolean positionsAreIntegerBcis(Map<?,?> position) {
    return position.values().stream().allMatch(v -> v instanceof Integer);
}

Try / catch

try {
    parser.parse();
} catch (ExperimentParserTypeError e) {
    // message names file, 'position', expected Integer, and the actual value; fix the JSON
}

Prevention

When it happens

Trigger: An optimization log whose position map contains a non-integer bci, e.g. "position": {"m(int)": "42"} (string), a float bci, or a null. Usually produced by a hand-edited log or a mismatched/buggy optimization-log writer version.

Common situations: Editing or programmatically generating optimization logs; JSON serializers that quote numbers or emit doubles; mixing logs produced by one GraalVM version with a profdiff from another whose schema drifted.

Understand the failure class

Related errors


AI-assisted analysis of oracle/graal@a66e9ccd1d (2026-08-14). Data as JSON: /api/errors/779c1f9a3498e4d3. Report an issue: GitHub.

Appendix: source

Thrown at compiler/src/org.graalvm.profdiff/src/org/graalvm/profdiff/parser/CompilationUnitTreeParser.java:157

            } else {
                optimizationPhase.addChild(parseOptimizationPhase(childMap));
            }
        }
        return optimizationPhase;
    }

    private Optimization parseOptimization(ExperimentJSONParser.JSONMap optimization) throws ExperimentParserTypeError {
        String optimizationName = optimization.property(OptimizationLogImpl.OPTIMIZATION_NAME_PROPERTY).asString();
        String eventName = optimization.property(OptimizationLogImpl.EVENT_NAME_PROPERTY).asString();
        ExperimentJSONParser.JSONLiteral positionObject = optimization.property(OptimizationLogImpl.POSITION_PROPERTY);
        Position position = Position.EMPTY;
        if (!positionObject.isNull()) {
            MapCursor<String, Object> cursor = positionObject.asMap().getInnerMap().getEntries();
            List<String> methodNames = new ArrayList<>();
            List<Integer> bcis = new ArrayList<>();
            while (cursor.advance()) {
                if (!(cursor.getValue() instanceof Integer)) {
                    throw new ExperimentParserTypeError(experimentId, fileView.getSymbolicPath(), OptimizationLogImpl.POSITION_PROPERTY, Integer.class, cursor.getValue());
                }
                methodNames.add(Method.removeMethodVariantKey(cursor.getKey()));
                bcis.add((Integer) cursor.getValue());
            }
            position = Position.create(methodNames, bcis);
        }
        EconomicMap<String, Object> properties = optimization.getInnerMap();
        properties.removeKey(OptimizationLogImpl.OPTIMIZATION_NAME_PROPERTY);
        properties.removeKey(OptimizationLogImpl.EVENT_NAME_PROPERTY);
        properties.removeKey(OptimizationLogImpl.POSITION_PROPERTY);
        return new Optimization(optimizationName, eventName, position, properties.isEmpty() ? null : properties);
    }
}

View on GitHub (pinned to a66e9ccd1d)