{"record":{"id":"dc73f9f0f7c04439","repo":"apache/druid","slug":"cannot-read-directly-out-of-datasource-s","errorCode":null,"errorMessage":"Cannot read directly out of dataSource: %s","messagePattern":"Cannot read directly out of dataSource: (.+?)","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"server/src/main/java/org/apache/druid/segment/MapSegmentWrangler.java","lineNumber":53,"sourceCode":"{\n  private final Map<Class<? extends DataSource>, SegmentWrangler> wranglers;\n\n  @Inject\n  public MapSegmentWrangler(final Map<Class<? extends DataSource>, SegmentWrangler> wranglers)\n  {\n    this.wranglers = wranglers;\n  }\n\n  @Override\n  public Iterable<Segment> getSegmentsForIntervals(final DataSource dataSource, final Iterable<Interval> intervals)\n  {\n    final SegmentWrangler wrangler = wranglers.get(dataSource.getClass());\n\n    if (wrangler != null) {\n      return wrangler.getSegmentsForIntervals(dataSource, intervals);\n    } else {\n      // Reasonable as a user-facing error message.\n      throw new ISE(\"Cannot read directly out of dataSource: %s\", dataSource);\n    }\n  }\n}\n","sourceCodeStart":35,"sourceCodeEnd":57,"githubUrl":"https://github.com/apache/druid/blob/9b90983fd291f26935af934383ce360473179e4d/server/src/main/java/org/apache/druid/segment/MapSegmentWrangler.java#L35-L57","documentation":"MapSegmentWrangler only knows how to produce segments for dataSources that have a registered SegmentWrangler for their concrete class. For other dataSource types (which normally reach the server via segment loading, not direct lookup) it throws this ISE with a user-facing message.","triggerScenarios":"Calling getSegmentsForIntervals on a MapSegmentWrangler with a dataSource class that has no entry in the wranglers map — e.g. a non-Broker/native dataSource type passed into an inline/lookup-style query path.","commonSituations":"Querying a datasource type that isn't wrangler-readable (tables, joins over non-map sources) via an API expecting a wrangler-backed source; extension code registering wranglers for only some DataSource subclasses.","solutions":["Only invoke this method for dataSource classes registered in the wranglers map (check dataSource.getClass() membership first).","Register a SegmentWrangler for the custom dataSource class in the WranglerModule/extension.","Route the query through the standard segment-loading path instead of direct wrangler lookup."],"exampleFix":"// before\nfinal List<SegmentId> segs = wrangler.getSegmentsForIntervals(anyDataSource, intervals);\n// after\nif (wrangler.getSupportedTypes().contains(dataSource.getClass())) {\n  final List<SegmentId> segs = wrangler.getSegmentsForIntervals(dataSource, intervals);\n}","handlingStrategy":"type-guard","validationCode":"boolean readable = wrangler.getSupportedTypes().contains(dataSource.getClass());","typeGuard":"if (dataSource instanceof InlineDataSource || wrangler.getSupportedTypes().contains(dataSource.getClass())) {\n  // safe to call getSegmentsForIntervals\n}","tryCatchPattern":null,"preventionTips":["Check getSupportedTypes() before invoking wrangler methods.","Register wranglers for every custom DataSource subclass you add."],"tags":["segment-wrangler","unsupported-operation","datasource"],"backgroundTag":"unsupported-operation","analyzedSha":"9b90983fd291f26935af934383ce360473179e4d","analyzedAt":"2026-09-07T13:32:30.957Z","contentChangedAt":"2026-09-07T13:32:30.957Z","schemaVersion":2},"datasetVersion":"2026-09-17T15:17:12.973Z"}