Skip to content

fix error reporting when plugin uses unsupported concurrency#19040

Open
yaauie wants to merge 1 commit into
elastic:mainfrom
yaauie:fix-error-reporting-unsupported-concurrency
Open

fix error reporting when plugin uses unsupported concurrency#19040
yaauie wants to merge 1 commit into
elastic:mainfrom
yaauie:fix-error-reporting-unsupported-concurrency

Conversation

@yaauie
Copy link
Copy Markdown
Member

@yaauie yaauie commented Apr 22, 2026

Release notes

  • Fixed an issue where installing and referencing a plugin that has an unsupported concurrency type resulted in an obscure error message

What does this PR do?

Improves the error message when a pipeline includes a plugin with an unsupported concurrency type. These types are declared in the plugin itself, not in the pipeline configuration.

Why is it important/What is the impact to the user?

It helps us chase down the real issue, instead of a separate issue that occurs while describing the available concurrency types.

Checklist

  • My code follows the style guidelines of this project
  • [ ] I have commented my code, particularly in hard-to-understand areas
  • [ ] I have made corresponding changes to the documentation
  • [ ] I have made corresponding change to the default configuration files (and/or docker env variables)
  • [ ] I have added tests that prove my fix is effective or that my feature works

How to test this PR locally

  1. Build normally
  2. Edit an output plugin in /vendor/bundle/jruby/*/gems/logstash-output-*/ to have concurrency :bananas` instead of one of the supported concurrency types
  3. Run logstash with a pipeline configuration that includes the edited plugin
  4. Observe the error message:
[2026-04-22T19:41:33,116][ERROR][logstash.agent           ] Failed to execute action {action: LogStash::PipelineAction::Create/pipeline_id:main, exception: "Java::JavaLang::IllegalStateException", message: "Unable to configure plugins: Could not find output delegator strategy of type ':bananas'. Supported strategies: :shared, :legacy, :single", backtrace: ["org.logstash.config.ir.CompiledPipeline.<init>(CompiledPipeline.java:167)", "org.logstash.execution.AbstractPipelineExt.initialize(AbstractPipelineExt.java:246)", "org.logstash.execution.AbstractPipelineExt$INVOKER$i$initialize.call(AbstractPipelineExt$INVOKER$i$initialize.gen)", "org.jruby.internal.runtime.methods.JavaMethod$JavaMethodN.call(JavaMethod.java:845)", "org.jruby.ir.runtime.IRRuntimeHelpers.instanceSuper(IRRuntimeHelpers.java:1380)", "org.jruby.ir.instructions.InstanceSuperInstr.interpret(InstanceSuperInstr.java:128)", "org.jruby.ir.interpreter.InterpreterEngine.processCall(InterpreterEngine.java:372)", "org.jruby.ir.interpreter.StartupInterpreterEngine.interpret(StartupInterpreterEngine.java:66)", "org.jruby.internal.runtime.methods.MixedModeIRMethod.INTERPRET_METHOD(MixedModeIRMethod.java:133)", "org.jruby.internal.runtime.methods.MixedModeIRMethod.call(MixedModeIRMethod.java:120)", "org.jruby.runtime.callsite.CachingCallSite.cacheAndCall(CachingCallSite.java:446)", "org.jruby.runtime.callsite.CachingCallSite.call(CachingCallSite.java:92)", "org.jruby.RubyClass.newInstance(RubyClass.java:1050)", "org.jruby.RubyClass$INVOKER$i$newInstance.call(RubyClass$INVOKER$i$newInstance.gen)", "org.jruby.runtime.callsite.CachingCallSite.cacheAndCall(CachingCallSite.java:446)", "org.jruby.runtime.callsite.CachingCallSite.call(CachingCallSite.java:92)", "org.jruby.ir.instructions.CallBase.interpret(CallBase.java:551)", "org.jruby.ir.interpreter.InterpreterEngine.processCall(InterpreterEngine.java:372)", "org.jruby.ir.interpreter.StartupInterpreterEngine.interpret(StartupInterpreterEngine.java:66)", "org.jruby.internal.runtime.methods.MixedModeIRMethod.INTERPRET_METHOD(MixedModeIRMethod.java:133)", "org.jruby.internal.runtime.methods.MixedModeIRMethod.call(MixedModeIRMethod.java:120)", "org.jruby.ir.targets.indy.InvokeSite.performIndirectCall(InvokeSite.java:893)", "org.jruby.ir.targets.indy.InvokeSite.invoke(InvokeSite.java:797)", "Users.rye.src.elastic.logstash_at_40_main.logstash_minus_core.lib.logstash.agent.️❤ {} converge_state #0(/Users/rye/src/elastic/logstash@main/logstash-core/lib/logstash/agent.rb:433)", "org.jruby.runtime.CompiledIRBlockBody.callDirect(CompiledIRBlockBody.java:141)", "org.jruby.runtime.MixedModeIRBlockBody.callDirect(MixedModeIRBlockBody.java:105)", "org.jruby.runtime.IRBlockBody.call(IRBlockBody.java:66)", "org.jruby.runtime.IRBlockBody.call(IRBlockBody.java:60)", "org.jruby.runtime.Block.call(Block.java:146)", "org.jruby.RubyProc.call(RubyProc.java:394)", "org.jruby.internal.runtime.RubyRunnable.run(RubyRunnable.java:123)", "java.base/java.lang.Thread.run(Thread.java:1583)"], cause: {exception: Java::JavaLang::IllegalArgumentException, message: "Could not find output delegator strategy of type ':bananas'. Value strategies: :shared, :legacy, :single", backtrace: ["org.logstash.config.ir.compiler.OutputStrategyExt$OutputStrategyRegistryExt.classFor(OutputStrategyExt.java:104)", "org.logstash.config.ir.compiler.OutputDelegatorExt.initialize(OutputDelegatorExt.java:77)", "org.logstash.config.ir.compiler.OutputDelegatorExt.initialize(OutputDelegatorExt.java:56)", "org.logstash.plugins.factory.PluginFactoryExt.plugin(PluginFactoryExt.java:241)", "org.logstash.plugins.factory.PluginFactoryExt.buildOutput(PluginFactoryExt.java:136)", "org.logstash.config.ir.CompiledPipeline.lambda$setupOutputs$0(CompiledPipeline.java:224)", "java.base/java.util.ArrayList.forEach(ArrayList.java:1596)", "org.logstash.config.ir.CompiledPipeline.setupOutputs(CompiledPipeline.java:220)", "org.logstash.config.ir.CompiledPipeline.<init>(CompiledPipeline.java:165)", "org.logstash.execution.AbstractPipelineExt.initialize(AbstractPipelineExt.java:246)", "org.logstash.execution.AbstractPipelineExt$INVOKER$i$initialize.call(AbstractPipelineExt$INVOKER$i$initialize.gen)", "org.jruby.internal.runtime.methods.JavaMethod$JavaMethodN.call(JavaMethod.java:845)", "org.jruby.ir.runtime.IRRuntimeHelpers.instanceSuper(IRRuntimeHelpers.java:1380)", "org.jruby.ir.instructions.InstanceSuperInstr.interpret(InstanceSuperInstr.java:128)", "org.jruby.ir.interpreter.InterpreterEngine.processCall(InterpreterEngine.java:372)", "org.jruby.ir.interpreter.StartupInterpreterEngine.interpret(StartupInterpreterEngine.java:66)", "org.jruby.internal.runtime.methods.MixedModeIRMethod.INTERPRET_METHOD(MixedModeIRMethod.java:133)", "org.jruby.internal.runtime.methods.MixedModeIRMethod.call(MixedModeIRMethod.java:120)", "org.jruby.runtime.callsite.CachingCallSite.cacheAndCall(CachingCallSite.java:446)", "org.jruby.runtime.callsite.CachingCallSite.call(CachingCallSite.java:92)", "org.jruby.RubyClass.newInstance(RubyClass.java:1050)", "org.jruby.RubyClass$INVOKER$i$newInstance.call(RubyClass$INVOKER$i$newInstance.gen)", "org.jruby.runtime.callsite.CachingCallSite.cacheAndCall(CachingCallSite.java:446)", "org.jruby.runtime.callsite.CachingCallSite.call(CachingCallSite.java:92)", "org.jruby.ir.instructions.CallBase.interpret(CallBase.java:551)", "org.jruby.ir.interpreter.InterpreterEngine.processCall(InterpreterEngine.java:372)", "org.jruby.ir.interpreter.StartupInterpreterEngine.interpret(StartupInterpreterEngine.java:66)", "org.jruby.internal.runtime.methods.MixedModeIRMethod.INTERPRET_METHOD(MixedModeIRMethod.java:133)", "org.jruby.internal.runtime.methods.MixedModeIRMethod.call(MixedModeIRMethod.java:120)", "org.jruby.ir.targets.indy.InvokeSite.performIndirectCall(InvokeSite.java:893)", "org.jruby.ir.targets.indy.InvokeSite.invoke(InvokeSite.java:797)", "Users.rye.src.elastic.logstash_at_40_main.logstash_minus_core.lib.logstash.agent.️❤ {} converge_state #0(/Users/rye/src/elastic/logstash@main/logstash-core/lib/logstash/agent.rb:433)", "org.jruby.runtime.CompiledIRBlockBody.callDirect(CompiledIRBlockBody.java:141)", "org.jruby.runtime.MixedModeIRBlockBody.callDirect(MixedModeIRBlockBody.java:105)", "org.jruby.runtime.IRBlockBody.call(IRBlockBody.java:66)", "org.jruby.runtime.IRBlockBody.call(IRBlockBody.java:60)", "org.jruby.runtime.Block.call(Block.java:146)", "org.jruby.RubyProc.call(RubyProc.java:394)", "org.jruby.internal.runtime.RubyRunnable.run(RubyRunnable.java:123)", "java.base/java.lang.Thread.run(Thread.java:1583)"]}}

Without this patch, the error message looks like:

[2026-04-22T19:44:08,521][ERROR][logstash.agent           ] Failed to execute action {action: LogStash::PipelineAction::Create/pipeline_id:main, exception: "Java::JavaLang::IllegalStateException", message: "Unable to configure plugins: (TypeError) wrong argument type LogStash::OutputDelegatorStrategies::Shared (expected String)", backtrace: ["org.logstash.config.ir.CompiledPipeline.<init>(CompiledPipeline.java:167)", "org.logstash.execution.AbstractPipelineExt.initialize(AbstractPipelineExt.java:246)", "org.logstash.execution.AbstractPipelineExt$INVOKER$i$initialize.call(AbstractPipelineExt$INVOKER$i$initialize.gen)", "org.jruby.internal.runtime.methods.JavaMethod$JavaMethodN.call(JavaMethod.java:845)", "org.jruby.ir.runtime.IRRuntimeHelpers.instanceSuper(IRRuntimeHelpers.java:1380)", "org.jruby.ir.instructions.InstanceSuperInstr.interpret(InstanceSuperInstr.java:128)", "org.jruby.ir.interpreter.InterpreterEngine.processCall(InterpreterEngine.java:372)", "org.jruby.ir.interpreter.StartupInterpreterEngine.interpret(StartupInterpreterEngine.java:66)", "org.jruby.internal.runtime.methods.MixedModeIRMethod.INTERPRET_METHOD(MixedModeIRMethod.java:133)", "org.jruby.internal.runtime.methods.MixedModeIRMethod.call(MixedModeIRMethod.java:120)", "org.jruby.runtime.callsite.CachingCallSite.cacheAndCall(CachingCallSite.java:446)", "org.jruby.runtime.callsite.CachingCallSite.call(CachingCallSite.java:92)", "org.jruby.RubyClass.newInstance(RubyClass.java:1050)", "org.jruby.RubyClass$INVOKER$i$newInstance.call(RubyClass$INVOKER$i$newInstance.gen)", "org.jruby.runtime.callsite.CachingCallSite.cacheAndCall(CachingCallSite.java:446)", "org.jruby.runtime.callsite.CachingCallSite.call(CachingCallSite.java:92)", "org.jruby.ir.instructions.CallBase.interpret(CallBase.java:551)", "org.jruby.ir.interpreter.InterpreterEngine.processCall(InterpreterEngine.java:372)", "org.jruby.ir.interpreter.StartupInterpreterEngine.interpret(StartupInterpreterEngine.java:66)", "org.jruby.internal.runtime.methods.MixedModeIRMethod.INTERPRET_METHOD(MixedModeIRMethod.java:133)", "org.jruby.internal.runtime.methods.MixedModeIRMethod.call(MixedModeIRMethod.java:120)", "org.jruby.ir.targets.indy.InvokeSite.performIndirectCall(InvokeSite.java:893)", "org.jruby.ir.targets.indy.InvokeSite.invoke(InvokeSite.java:797)", "Users.rye.src.elastic.logstash_at_40_main.logstash_minus_core.lib.logstash.agent.️❤ {} converge_state #0(/Users/rye/src/elastic/logstash@main/logstash-core/lib/logstash/agent.rb:433)", "org.jruby.runtime.CompiledIRBlockBody.callDirect(CompiledIRBlockBody.java:141)", "org.jruby.runtime.MixedModeIRBlockBody.callDirect(MixedModeIRBlockBody.java:105)", "org.jruby.runtime.IRBlockBody.call(IRBlockBody.java:66)", "org.jruby.runtime.IRBlockBody.call(IRBlockBody.java:60)", "org.jruby.runtime.Block.call(Block.java:146)", "org.jruby.RubyProc.call(RubyProc.java:394)", "org.jruby.internal.runtime.RubyRunnable.run(RubyRunnable.java:123)", "java.base/java.lang.Thread.run(Thread.java:1583)"], cause: {exception: Java::OrgJrubyExceptions::TypeError, message: "(TypeError) wrong argument type LogStash::OutputDelegatorStrategies::Shared (expected String)", backtrace: ["org.logstash.config.ir.compiler.OutputDelegatorExt.initialize(org/logstash/config/ir/compiler/OutputDelegatorExt.java:77)", "org.logstash.config.ir.compiler.OutputDelegatorExt.initialize(org/logstash/config/ir/compiler/OutputDelegatorExt.java:56)", "org.logstash.plugins.factory.PluginFactoryExt.plugin(org/logstash/plugins/factory/PluginFactoryExt.java:241)", "org.logstash.execution.AbstractPipelineExt.initialize(org/logstash/execution/AbstractPipelineExt.java:246)", "RUBY.initialize(/Users/rye/src/elastic/logstash@main/logstash-core/lib/logstash/java_pipeline.rb:47)", "org.jruby.RubyClass.new(org/jruby/RubyClass.java:1050)", "RUBY.execute(/Users/rye/src/elastic/logstash@main/logstash-core/lib/logstash/pipeline_action/create.rb:50)", "Users.rye.src.elastic.logstash_at_40_main.logstash_minus_core.lib.logstash.agent.converge_state(/Users/rye/src/elastic/logstash@main/logstash-core/lib/logstash/agent.rb:433)"]}}

Related issues

Use cases

Screenshots

Logs

@github-actions
Copy link
Copy Markdown
Contributor

🤖 GitHub comments

Just comment with:

  • run docs-build : Re-trigger the docs validation. (use unformatted text in the comment!)
  • run exhaustive tests : Run the exhaustive tests Buildkite pipeline.

String.format(
"Could not find output delegator strategy of type '%s'. Value strategies: %s",
type.asJavaString(),
map.values(context).stream().map(v -> ((IRubyObject) v).asJavaString())
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IRubyObject#asJavaString has a base implementation in RubyBasicObject that throws a type-error unless the IRubyObject is string-like (e.g., trivially coercible to a string), so it doesn't work well with the RubyClass instances that are values in the map.

@mergify
Copy link
Copy Markdown
Contributor

mergify Bot commented Apr 22, 2026

This pull request does not have a backport label. Could you fix it @yaauie? 🙏
To fixup this pull request, you need to add the backport labels for the needed
branches, such as:

  • backport-8./d is the label to automatically backport to the 8./d branch. /d is the digit.
  • If no backport is necessary, please add the backport-skip label

@elasticmachine
Copy link
Copy Markdown

💚 Build Succeeded

@yaauie yaauie mentioned this pull request Apr 22, 2026
7 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants