{"record":{"id":"5e9ec263d24ca871","repo":"redis/jedis","slug":"hashimport-name-has-been-discarded","errorCode":null,"errorMessage":"HashImport '<name>' has been discarded","messagePattern":"HashImport '<name>' has been discarded","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"src/main/java/redis/clients/jedis/HashImportSupport.java","lineNumber":19,"sourceCode":"package redis.clients.jedis;\n\n/**\n * {@code HIMPORT SET} helpers: client-side argument validation, and the per-connection\n * prepare-before-use that a {@code himportSet} {@link CommandObject}'s\n * {@linkplain CommandObject#getPreProcessHooks() pre-process hook} runs. The hook is invoked by\n * {@link Connection#executeCommand(CommandObject)} once the {@code CommandExecutor} has picked a\n * connection &mdash; so retry / cluster redirection / failover stay in force &mdash; injecting a\n * {@code PREPARE} on that connection just before the {@code SET} when the fieldset is not yet\n * prepared there.\n */\nfinal class HashImportSupport {\n\n  private HashImportSupport() {\n  }\n\n  static void checkArgs(HashImport fieldset, int valueCount) {\n    if (fieldset.isDiscarded()) {\n      throw new IllegalStateException(\"HashImport '\" + fieldset.name() + \"' has been discarded\");\n    }\n    if (valueCount != fieldset.size()) {\n      throw new IllegalArgumentException(\"HashImport '\" + fieldset.name() + \"' expects \"\n          + fieldset.size() + \" values but got \" + valueCount);\n    }\n  }\n\n  /**\n   * Prepare-before-use: if {@code fieldset} is not yet prepared on {@code connection}, send\n   * {@code HIMPORT PREPARE} and record it in the connection's note. The PREPARE is built here, only\n   * when actually needed &mdash; the common already-prepared case allocates nothing. The caller\n   * must own the connection.\n   */\n  static void prepareBeforeUse(Connection connection, HashImport fieldset) {\n    if (!connection.himportState().isPrepared(fieldset.name())) {\n      connection.executeCommand(new CommandArguments(Protocol.Command.HIMPORT)\n          .add(Protocol.Keyword.PREPARE).add(fieldset.name()).addObjects(fieldset.fields()));\n      markPrepared(connection, fieldset);","sourceCodeStart":1,"sourceCodeEnd":37,"githubUrl":"https://github.com/redis/jedis/blob/6dac31d4c224fb3257c216f3985340c6f500cdcb/src/main/java/redis/clients/jedis/HashImportSupport.java#L1-L37","documentation":"HashImportSupport.checkArgs validates a HashImport (a Redis hash-field import fieldset) before use. It throws IllegalStateException when the fieldset has already been discarded (e.g. after a failed prepare or explicit discard), since using it afterward would send stale or invalid state to the server. The name in the message identifies which fieldset was misused.","triggerScenarios":"Calling a hash-import command method with a HashImport fieldset after discard() was called on it, or after a failed prepare(Connection) left it discarded. checkArgs is invoked as the first step of every fieldset-consuming API call.","commonSituations":"Reusing a fieldset across two import calls where the first failed mid-way; catching an exception from a previous import and retrying with the same, now-discarded, HashImport object; long-lived fieldset objects held in application state that were discarded during a connection reset.","solutions":["Create a new HashImport fieldset instance instead of reusing the discarded one","Check fieldset.isDiscarded() before each import call and rebuild if true","Fix the root cause that led to the discard (usually a failed prepare/connection error) before retrying"],"exampleFix":"// before\nHashImport fieldset = buildFieldset();\ntry {\n  jedis.himport(namespace, key, fieldset, values);\n} catch (JedisException e) {\n  jedis.himport(namespace, key, fieldset, values); // IllegalStateException: discarded\n}\n// after\nHashImport fieldset = buildFieldset();\ntry {\n  jedis.himport(namespace, key, fieldset, values);\n} catch (JedisException e) {\n  HashImport fresh = buildFieldset();\n  jedis.himport(namespace, key, fresh, values);\n}","handlingStrategy":"validation","validationCode":"if (fieldset == null || fieldset.isDiscarded()) {\n  fieldset = rebuildFieldset();\n}","typeGuard":"boolean usable(HashImport fs) { return fs != null && !fs.isDiscarded(); }","tryCatchPattern":"try {\n  hashImportCall(fieldset, values);\n} catch (IllegalStateException e) {\n  if (e.getMessage().contains(\"discarded\")) {\n    fieldset = rebuildFieldset();\n    hashImportCall(fieldset, values);\n  } else throw e;\n}","preventionTips":["Rebuild the fieldset for every import attempt instead of reusing instances","Check isDiscarded() before each use when fieldsets are long-lived","Wrap import retries in logic that constructs fresh fieldsets"],"tags":["state","illegal-state","redis","hash-import"],"backgroundTag":"invalid-state-transition","analyzedSha":"6dac31d4c224fb3257c216f3985340c6f500cdcb","analyzedAt":"2026-09-08T04:55:01.204Z","contentChangedAt":"2026-09-08T04:55:01.204Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}