{"record":{"id":"880d64c439a8dad1","repo":"apache/iceberg","slug":"s-does-not-expose-configuration-properties","errorCode":null,"errorMessage":"%s does not expose configuration properties","messagePattern":"(.+?) does not expose configuration properties","errorType":"exception","errorClass":"UnsupportedOperationException","httpStatus":null,"severity":"warning","filePath":"api/src/main/java/org/apache/iceberg/io/FileIO.java","lineNumber":107,"sourceCode":"  /** Convenience method to {@link #deleteFile(String) delete} an {@link InputFile}. */\n  default void deleteFile(InputFile file) {\n    deleteFile(file.location());\n  }\n\n  /** Convenience method to {@link #deleteFile(String) delete} an {@link OutputFile}. */\n  default void deleteFile(OutputFile file) {\n    deleteFile(file.location());\n  }\n\n  /**\n   * Returns the property map used to configure this FileIO\n   *\n   * @return the property map used to configure this FileIO\n   * @throws UnsupportedOperationException if this FileIO does not expose its configuration\n   *     properties\n   */\n  default Map<String, String> properties() {\n    throw new UnsupportedOperationException(\n        String.format(\"%s does not expose configuration properties\", this.getClass()));\n  }\n\n  /**\n   * Initialize File IO from catalog properties.\n   *\n   * @param properties catalog properties\n   */\n  default void initialize(Map<String, String> properties) {}\n\n  /**\n   * Close File IO to release underlying resources.\n   *\n   * <p>Calling this method is only required when this FileIO instance is no longer expected to be\n   * used, and the resources it holds need to be explicitly released to avoid resource leaks.\n   */\n  @Override\n  default void close() {}","sourceCodeStart":89,"sourceCodeEnd":125,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/api/src/main/java/org/apache/iceberg/io/FileIO.java#L89-L125","documentation":"FileIO.properties() is a default method that returns the configuration map used to initialize the FileIO. Implementations are not required to expose their configuration; the default implementation throws UnsupportedOperationException naming the concrete class. Callers must treat property exposure as optional capability.","triggerScenarios":"Calling properties() on a FileIO implementation that does not override properties() — e.g. a custom FileIO, HadoopFileIO in some configurations, or any implementation built before the method existed.","commonSituations":"Debugging/catalog code introspecting a FileIO's config; util code copying configuration between FileIO instances; upgrading Iceberg and calling properties() on custom FileIO classes written against the older interface.","solutions":["Implement properties() in your FileIO class to return the map passed to initialize(Map<String,String>)","Wrap the call in a try/catch for UnsupportedOperationException and fall back to tracking config at the call site","Pass and retain the configuration separately (you already hold the map you gave to initialize())"],"exampleFix":"// before\nMap<String, String> conf = io.properties();\n// after\nMap<String, String> conf;\ntry {\n  conf = io.properties();\n} catch (UnsupportedOperationException e) {\n  conf = retainedConfigAtConstruction; // config captured when initialize() was called\n}","handlingStrategy":"try-catch","validationCode":"// capability probe\nboolean exposesProps;\ntry { io.properties(); exposesProps = true; } catch (UnsupportedOperationException e) { exposesProps = false; }","typeGuard":null,"tryCatchPattern":"try { conf = io.properties(); } catch (UnsupportedOperationException e) { conf = myRetainedConfig; }","preventionTips":["Override properties() in custom FileIO implementations to return the initialize() config","Keep your own copy of the config map passed to initialize()","Check the FileIO implementation docs before relying on properties()","Wrap introspection utilities in capability checks rather than assuming the method works"],"tags":["io","fileio","configuration","unsupported"],"backgroundTag":"method-not-implemented","analyzedSha":"86d9c8fc543e7c56c9f624eb725f76c9baff9570","analyzedAt":"2026-09-12T00:46:39.097Z","contentChangedAt":"2026-09-12T00:46:39.097Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}