crewai - ✅(Solved) Fix [BUG]crew.kickoff() truncates LLM output but task.execute_sync() works correctly [2 pull requests, 2 comments, 2 participants]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…
GitHub stats
crewAIInc/crewAI#4603Fetched 2026-04-08 00:41:05
View on GitHub
Comments
2
Participants
2
Timeline
8
Reactions
0
Timeline (top)
commented ×2cross-referenced ×2labeled ×2closed ×1

When using crew.kickoff() to execute a single-agent, single-task crew, the output is severely truncated (7-227 characters instead of 2500-5700 characters). However, calling task.execute_sync(agent) directly on the same task and agent produces complete output.

Issue affects both OpenAI and Bedrock providers, suggesting it's a CrewAI Crew orchestration issue, not provider-specific.

Error Message

| ChatBedrockConverse | Bedrock | N/A | ❌ Auth error | | ChatBedrockConverse | Bedrock | N/A | ❌ Auth error |

Root Cause

Possible Root Causes in CrewAI Code

Fix Action

Fix / Workaround

Workaround that Works

Workaround for Production

HIGH - This bug affects any CrewAI usage where LLM responses exceed ~250 characters, which is most real-world applications. The workaround requires bypassing CrewAI's main orchestration API (crew.kickoff()), defeating the purpose of using CrewAI.

PR fix notes

PR #4604: fix: prevent LLM stop words mutation causing output truncation in crew.kickoff()

Description (problem / solution / changelog)

fix: prevent LLM stop words mutation causing output truncation (#4603)

Summary

CrewAgentExecutor.__init__ was permanently mutating the shared LLM object's stop attribute by adding executor-specific stop words (e.g., "\nObservation:"). This caused BaseLLM._apply_stop_words() to truncate ALL subsequent LLM responses at those stop words — even calls from later crews/tasks where stop words were not intended. The old code even had a comment acknowledging this: "This may be mutating the shared llm object and needs further evaluation".

The fix makes stop word management scoped to each execution:

  • __init__: Saves the LLM's original stop words into _original_llm_stop instead of mutating llm.stop.
  • _set_llm_stop_words(): Merges executor stop words onto the LLM at the start of invoke/ainvoke.
  • _restore_llm_stop_words(): Restores the original stop words in a finally block, guaranteeing cleanup even on exceptions.
  • _update_executor_parameters in agent/core.py: No longer mutates llm.stop; only updates the saved original snapshot.

18 new unit tests cover init behavior, set/restore lifecycle, exception safety, multiple sequential executors sharing an LLM, user-configured stop word preservation, and edge cases (None LLM, None stop, empty stop).

Review & Testing Checklist for Human

  • Concurrency safety: The fix sets/restores stop words on the shared LLM during invoke. If two executors sharing the same LLM instance run concurrently (e.g., async parallel tasks), they could still interfere. Verify whether concurrent execution with a shared LLM is a supported pattern.
  • End-to-end verification: The tests are all mocked. This fix should be verified with a real crew.kickoff() workflow that previously exhibited the truncation (e.g., the reproduction in issue #4603) to confirm the truncation is actually resolved.
  • No code path depends on llm.stop being set after create_agent_executor but before invoke: The old code set stop words eagerly at init time. The new code defers to invoke time. Verify no intermediate code reads llm.stop expecting executor stop words to already be present.

Notes

Changed files

  • lib/crewai/src/crewai/agent/core.py (modified, +7/-7)
  • lib/crewai/src/crewai/agents/crew_agent_executor.py (modified, +36/-9)
  • lib/crewai/tests/agents/test_stop_words_mutation.py (added, +489/-0)

PR #4669: fix(crew): preserve full task output in crew.kickoff() (fixes #4603)

Description (problem / solution / changelog)

Summary

Fixes #4603 — crew.kickoff() was truncating LLM output when an agent was reused across multiple crew runs.

Root Cause

When CrewAgentExecutor is reused (via _update_executor_parameters), the messages list and iterations counter were not reset between invocations. This caused:

  1. Message accumulation: Old system/user/assistant messages from previous runs were prepended to new prompts, confusing the LLM and potentially exceeding context windows
  2. Iteration counter leak: The iteration counter continued from the previous run, potentially triggering premature max_iterations handling

The experimental executor already handles this correctly (resetting state at the top of invoke()), but the main CrewAgentExecutor did not.

Changes

  • lib/crewai/src/crewai/agents/crew_agent_executor.py: Reset self.messages = [] and self.iterations = 0 at the start of both invoke() and ainvoke() methods
  • lib/crewai/tests/test_executor_state_reset.py: 5 tests covering:
    • Direct state reset verification
    • Full output preservation with reused agents
    • Output consistency between CrewOutput.raw and TaskOutput.raw
    • No truncation across 5 sequential kickoff runs
    • Executor-level message/iteration reset verification

Why this is safe

  • The constructor already initializes messages = [] and iterations = 0
  • _setup_messages() only appends (never clears), so it needs a clean slate
  • This matches the pattern in the experimental executor (self.state.messages.clear(), self.state.iterations = 0)

Fixes #4603

<!-- CURSOR_SUMMARY -->

[!NOTE] Medium Risk Touches core CrewAgentExecutor execution flow by clearing messages and iterations on every invoke()/ainvoke(), which could affect any callers relying on cross-invocation conversation state. Added tests reduce regression risk and primarily cover the reported output-truncation/reuse scenario.

Overview Fixes executor reuse leaking state by resetting CrewAgentExecutor.messages and the iteration counter at the start of both invoke() and ainvoke(), preventing accumulated prompts and premature max-iteration behavior when the executor is reused across crew.kickoff() runs.

Adds a new test_executor_state_reset.py suite that repeatedly reuses the same agent/executor across multiple kickoffs/invocations and asserts outputs are not truncated and that CrewOutput.raw matches the underlying TaskOutput.raw.

<sup>Written by Cursor Bugbot for commit fae913a43e29552444e77b84baf8ccf0db3f8ec4. This will update automatically on new commits. Configure here.</sup>

<!-- /CURSOR_SUMMARY -->

Changed files

  • lib/crewai/src/crewai/agents/crew_agent_executor.py (modified, +4/-0)
  • lib/crewai/tests/test_executor_state_reset.py (added, +391/-0)

Code Example

---

Note: Output ends abruptly at "financ..." (total 227 chars)

## Workaround that Works

Calling `task.execute_sync(agent)` directly instead of `crew.kickoff()` produces complete output:

---

## Minimal Reproduction Case

### Test Case 1: Using crew.kickoff() (FAILS)

---

{
      "selected_factors": [
        {
          "identifier": "...",
          "name": "...",
          "description": "...",
          "country": "United States",
          "currency": "USD"
        }
      ]
    }

---

### Test Case 2: Using task.execute_sync() (WORKS)

---

## Detailed Investigation Results

### Evidence from Diagnostic Tests

| Test Method | Provider | Output Length | Status |
|-------------|----------|---------------|--------|
| litellm.completion() direct | Bedrock | 250 chars |Complete |
| ChatBedrockConverse | Bedrock | N/A |Auth error |
| crew.kickoff() isolated test | OpenAI | 2552 chars |Complete |
| crew.kickoff() in workflow | OpenAI | 7 chars |Truncated |
| crew.kickoff() in workflow | Bedrock | 7 chars |Truncated |
| task.execute_sync() in workflow | OpenAI | 3981 chars |Complete |

**Key Finding**: The isolated test with `crew.kickoff()` worked (2552 chars), but the same code in the full workflow failed (7 chars). This suggests interaction between multiple crew executions or some state issue.

### Truncation Patterns Observed

1. **Minimum truncation**: Exactly "

---

if isinstance(agent.llm, BedrockCompletion):
    if agent.llm.max_tokens is None:
        agent.llm.max_tokens = 4096

---

# Instead of:
# crew = Crew(agents=[agent], tasks=[task], ...)
# result = crew.kickoff()

# Use:
task.execute_sync(agent=agent)
output = task.output.raw

---

from crewai import Agent, Task, Crew, Process
from pathlib import Path

# Create agent
agent = Agent(
    role="Test Agent",
    goal="Return a large JSON response",
    backstory="You are a test agent that returns detailed JSON.",
    llm="openai/gpt-4o-mini",  # Also fails with bedrock/anthropic.claude-3-haiku-20240307-v1:0
    verbose=True,
    max_iter=3,
)

# Create task that should return large JSON (~2500+ chars)
task = Task(
    description="""Return a JSON object listing 5 US Treasury risk factors with detailed descriptions.

    For EACH factor provide:
    - identifier: factor ID
    - name: factor name
    - description: 2-3 sentences about the factor
    - country: United States
    - currency: USD

    Expected JSON format:

---

""",
    expected_output="A JSON object with selected_factors array containing 5 detailed factor entries",
    agent=agent,
)

# Method 1: Using crew.kickoff() - FAILS (truncated)
crew = Crew(
    agents=[agent],
    tasks=[task],
    process=Process.sequential,
    verbose=True,
    memory=False,
)

result = crew.kickoff()

# Extract output
output = None
if hasattr(result, 'raw'):
    output = result.raw
elif hasattr(result, 'output'):
    output = result.output
elif task.output and hasattr(task.output, 'raw'):
    output = task.output.raw

print(f"crew.kickoff() output length: {len(output) if output else 0}")
print(f"crew.kickoff() output preview: {output[:500] if output else 'None'}")
# Expected: 2500+ chars
# Actual: 7-227 chars (truncated)

---

# Same agent and task as above

# Method 2: Using task.execute_sync() - WORKS (complete)
task.execute_sync(agent=agent)
output = task.output.raw if task.output else None

print(f"execute_sync() output length: {len(output) if output else 0}")
print(f"execute_sync() output preview: {output[:500] if output else 'None'}")
# Expected: 2500+ chars
# Actual: 2500+ chars (complete!)

---

# Instead of:
# crew = Crew(agents=[agent], tasks=[task], ...)
# result = crew.kickoff()

# Use:
task.execute_sync(agent=agent)
output = task.output.raw
RAW_BUFFERClick to expand / collapse

Description

CrewAI Bug Report: crew.kickoff() Truncates Output vs Task.execute_sync()

Summary

When using crew.kickoff() to execute a single-agent, single-task crew, the output is severely truncated (7-227 characters instead of 2500-5700 characters). However, calling task.execute_sync(agent) directly on the same task and agent produces complete output.

Issue affects both OpenAI and Bedrock providers, suggesting it's a CrewAI Crew orchestration issue, not provider-specific.

Environment

  • CrewAI Version: Latest (as of 2026-02-25)
  • Python: 3.12
  • OS: macOS (Darwin 25.3.0)
  • LLM Providers Tested:
    • OpenAI (gpt-4o-mini) - ✅ Works with execute_sync(), ❌ Fails with crew.kickoff()
    • AWS Bedrock (anthropic.claude-3-haiku, anthropic.claude-sonnet-4-6) - ✅ Works with litellm direct, ❌ Fails with crew.kickoff()

Expected Behavior

crew.kickoff() should return the complete LLM-generated output from the task, which is 2500-5700 characters of valid JSON.

Actual Behavior

crew.kickoff() returns only the first 7-227 characters of output, typically truncated mid-sentence like:

```json
{
    "selected_factors": [
        {
            "identifier": "CX_IRC_TRS_US_USD",
            "name": "USD Government Bond Yield Curve",
            "category": "Interest",
            "description": "Treasury Zero Interest Rate Curve for United States of America USD. The Treasury yield curve represents the yields (interest rates) on government bonds across different maturities (e.g., 3-month, 2-year, 10-year, 30-year). It is one of the most important indicators in financ...

Note: Output ends abruptly at "financ..." (total 227 chars)

Workaround that Works

Calling task.execute_sync(agent) directly instead of crew.kickoff() produces complete output:

# ❌ FAILS - Truncated output (7-227 chars)
crew = Crew(
    agents=[agent],
    tasks=[task],
    process=Process.sequential,
    verbose=True,
    memory=False,
)
result = crew.kickoff()
output = result.raw  # Only 7-227 characters!

# ✅ WORKS - Complete output (2500-5700 chars)
task.execute_sync(agent=agent)
output = task.output.raw  # Full response!

Minimal Reproduction Case

Test Case 1: Using crew.kickoff() (FAILS)

from crewai import Agent, Task, Crew, Process
from pathlib import Path

# Create agent
agent = Agent(
    role="Test Agent",
    goal="Return a large JSON response",
    backstory="You are a test agent that returns detailed JSON.",
    llm="openai/gpt-4o-mini",  # Also fails with bedrock/anthropic.claude-3-haiku-20240307-v1:0
    verbose=True,
    max_iter=3,
)

# Create task that should return large JSON (~2500+ chars)
task = Task(
    description="""Return a JSON object listing 5 US Treasury risk factors with detailed descriptions.

    For EACH factor provide:
    - identifier: factor ID
    - name: factor name
    - description: 2-3 sentences about the factor
    - country: United States
    - currency: USD

    Expected JSON format:
    ```json
    {
      "selected_factors": [
        {
          "identifier": "...",
          "name": "...",
          "description": "...",
          "country": "United States",
          "currency": "USD"
        }
      ]
    }
    ```
    """,
    expected_output="A JSON object with selected_factors array containing 5 detailed factor entries",
    agent=agent,
)

# Method 1: Using crew.kickoff() - FAILS (truncated)
crew = Crew(
    agents=[agent],
    tasks=[task],
    process=Process.sequential,
    verbose=True,
    memory=False,
)

result = crew.kickoff()

# Extract output
output = None
if hasattr(result, 'raw'):
    output = result.raw
elif hasattr(result, 'output'):
    output = result.output
elif task.output and hasattr(task.output, 'raw'):
    output = task.output.raw

print(f"crew.kickoff() output length: {len(output) if output else 0}")
print(f"crew.kickoff() output preview: {output[:500] if output else 'None'}")
# Expected: 2500+ chars
# Actual: 7-227 chars (truncated)

Test Case 2: Using task.execute_sync() (WORKS)

# Same agent and task as above

# Method 2: Using task.execute_sync() - WORKS (complete)
task.execute_sync(agent=agent)
output = task.output.raw if task.output else None

print(f"execute_sync() output length: {len(output) if output else 0}")
print(f"execute_sync() output preview: {output[:500] if output else 'None'}")
# Expected: 2500+ chars
# Actual: 2500+ chars (complete!)

Detailed Investigation Results

Evidence from Diagnostic Tests

Test MethodProviderOutput LengthStatus
litellm.completion() directBedrock250 chars✅ Complete
ChatBedrockConverseBedrockN/A❌ Auth error
crew.kickoff() isolated testOpenAI2552 chars✅ Complete
crew.kickoff() in workflowOpenAI7 chars❌ Truncated
crew.kickoff() in workflowBedrock7 chars❌ Truncated
task.execute_sync() in workflowOpenAI3981 chars✅ Complete

Key Finding: The isolated test with crew.kickoff() worked (2552 chars), but the same code in the full workflow failed (7 chars). This suggests interaction between multiple crew executions or some state issue.

Truncation Patterns Observed

  1. Minimum truncation: Exactly "```json" (7 characters)
  2. Moderate truncation: 227 characters, cuts off mid-word
  3. No truncation: 2500-5700 characters when using execute_sync()

The fact that output is truncated to exactly "```json" suggests CrewAI is stopping output capture at a specific point, possibly:

  • Buffer size limit
  • Stream reading stopping early
  • Task completion signaled prematurely
  • Output object has size limits

What We've Ruled Out

NOT a provider issue - Happens with both OpenAI and Bedrock ❌ NOT an LLM token limit - litellm direct calls work fine ❌ NOT max_tokens configuration - Setting max_tokens=4096 doesn't help with crew.kickoff() ❌ NOT task definition - Same task works with execute_sync() ❌ NOT agent configuration - Same agent works with execute_sync()

IS a Crew orchestration issue - Only crew.kickoff() fails

Additional Context

Bedrock-Specific Finding

CrewAI's BedrockCompletion has max_tokens=None by default, which causes Bedrock API to use a low default (~256 tokens). We fixed this by setting:

if isinstance(agent.llm, BedrockCompletion):
    if agent.llm.max_tokens is None:
        agent.llm.max_tokens = 4096

However, this fix alone doesn't solve the crew.kickoff() truncation issue - it only helps when using execute_sync().

Possible Root Causes in CrewAI Code

Based on investigation, the issue may be in:

  1. Crew.kickoff() output handling - May have buffer/size limits
  2. Task output object assignment - crew.kickoff() may not properly assign task.output
  3. Streaming/buffering logic - May stop reading LLM stream early
  4. Multiple crew interactions - State pollution between successive crew.kickoff() calls

Steps to Reproduce

  1. Create an agent with any LLM (OpenAI or Bedrock)
  2. Create a task that expects 2000+ character JSON output
  3. Create a Crew with the agent and task
  4. Call crew.kickoff() and check result.raw length
  5. Compare with calling task.execute_sync(agent) and checking task.output.raw length

Workaround for Production

Replace all crew.kickoff() calls with direct task.execute_sync():

# Instead of:
# crew = Crew(agents=[agent], tasks=[task], ...)
# result = crew.kickoff()

# Use:
task.execute_sync(agent=agent)
output = task.output.raw

This works reliably and produces complete output.

Impact

HIGH - This bug affects any CrewAI usage where LLM responses exceed ~250 characters, which is most real-world applications. The workaround requires bypassing CrewAI's main orchestration API (crew.kickoff()), defeating the purpose of using CrewAI.

Request

Please investigate the Crew.kickoff() implementation to identify where output is being truncated. The fact that task.execute_sync() works suggests the issue is in the Crew orchestration layer, not the underlying task execution.


Generated: 2026-02-25 Reporter: System running risk factor selection agents Test Files: Available upon request (test_rfsa_minimal.py, test_bedrock_output_truncation.py)

Steps to Reproduce

  1. Create an agent with any LLM (OpenAI or Bedrock)
  2. Create a task that expects 2000+ character JSON output
  3. Create a Crew with the agent and task
  4. Call crew.kickoff() and check result.raw length
  5. Compare with calling task.execute_sync(agent) and checking task.output.raw length

Expected behavior

crew.kickoff() should return the complete LLM-generated output from the task, which is 2500-5700 characters of valid JSON.

Screenshots/Code snippets

Test Case 1: Using crew.kickoff() (FAILS)

from crewai import Agent, Task, Crew, Process
from pathlib import Path

# Create agent
agent = Agent(
    role="Test Agent",
    goal="Return a large JSON response",
    backstory="You are a test agent that returns detailed JSON.",
    llm="openai/gpt-4o-mini",  # Also fails with bedrock/anthropic.claude-3-haiku-20240307-v1:0
    verbose=True,
    max_iter=3,
)

# Create task that should return large JSON (~2500+ chars)
task = Task(
    description="""Return a JSON object listing 5 US Treasury risk factors with detailed descriptions.

    For EACH factor provide:
    - identifier: factor ID
    - name: factor name
    - description: 2-3 sentences about the factor
    - country: United States
    - currency: USD

    Expected JSON format:
    ```json
    {
      "selected_factors": [
        {
          "identifier": "...",
          "name": "...",
          "description": "...",
          "country": "United States",
          "currency": "USD"
        }
      ]
    }
    ```
    """,
    expected_output="A JSON object with selected_factors array containing 5 detailed factor entries",
    agent=agent,
)

# Method 1: Using crew.kickoff() - FAILS (truncated)
crew = Crew(
    agents=[agent],
    tasks=[task],
    process=Process.sequential,
    verbose=True,
    memory=False,
)

result = crew.kickoff()

# Extract output
output = None
if hasattr(result, 'raw'):
    output = result.raw
elif hasattr(result, 'output'):
    output = result.output
elif task.output and hasattr(task.output, 'raw'):
    output = task.output.raw

print(f"crew.kickoff() output length: {len(output) if output else 0}")
print(f"crew.kickoff() output preview: {output[:500] if output else 'None'}")
# Expected: 2500+ chars
# Actual: 7-227 chars (truncated)

Test Case 2: Using task.execute_sync() (WORKS)

# Same agent and task as above

# Method 2: Using task.execute_sync() - WORKS (complete)
task.execute_sync(agent=agent)
output = task.output.raw if task.output else None

print(f"execute_sync() output length: {len(output) if output else 0}")
print(f"execute_sync() output preview: {output[:500] if output else 'None'}")
# Expected: 2500+ chars
# Actual: 2500+ chars (complete!)

Operating System

Other (specify in additional context)

Python Version

3.12

crewAI Version

Latest (as of 2026-02-25)

crewAI Tools Version

  • OpenAI (gpt-4o-mini) - ✅ Works with execute_sync(), ❌ Fails with crew.kickoff() - AWS Bedrock (anthropic.claude-3-haiku, anthropic.claude-sonnet-4-6) - ✅ Works with litellm direct, ❌ Fails with crew.kickoff()

Virtual Environment

Venv

Evidence

Evidence from Diagnostic Tests

Test MethodProviderOutput LengthStatus
litellm.completion() directBedrock250 chars✅ Complete
ChatBedrockConverseBedrockN/A❌ Auth error
crew.kickoff() isolated testOpenAI2552 chars✅ Complete
crew.kickoff() in workflowOpenAI7 chars❌ Truncated
crew.kickoff() in workflowBedrock7 chars❌ Truncated
task.execute_sync() in workflowOpenAI3981 chars✅ Complete

Key Finding: The isolated test with crew.kickoff() worked (2552 chars), but the same code in the full workflow failed (7 chars). This suggests interaction between multiple crew executions or some state issue.

Possible Solution

Workaround for Production

Replace all crew.kickoff() calls with direct task.execute_sync():

# Instead of:
# crew = Crew(agents=[agent], tasks=[task], ...)
# result = crew.kickoff()

# Use:
task.execute_sync(agent=agent)
output = task.output.raw

This works reliably and produces complete output.

Additional context

  • OpenAI (gpt-4o-mini) - ✅ Works with execute_sync(), ❌ Fails with crew.kickoff()
  • AWS Bedrock (anthropic.claude-3-haiku, anthropic.claude-sonnet-4-6) - ✅ Works with litellm direct, ❌ Fails with crew.kickoff()

extent analysis

Fix Plan

To address the issue of truncated output when using crew.kickoff(), we need to modify the way output is handled in the Crew class.

Here are the steps to fix the issue:

  • Modify the Crew.kickoff() method to properly handle output from tasks.
  • Ensure that the output is not truncated when assigning it to the result object.
  • Update the Task class to handle large outputs correctly.

Code Changes

# In the Crew class
def kickoff(self):
    # ... existing code ...
    result = []
    for task in self.tasks:
        task_output = task.execute_sync(self.agents[0])
        result.append(task_output.raw)
    return '\n'.join(result)

# In the Task class
def execute_sync(self, agent):
    # ... existing code ...
    output = self.llm.generate(self.description)
    self.output.raw = output
    return self.output

Verification

To verify that the fix worked, you can use the following test cases:

# Test Case 1: Using crew.kickoff()
crew = Crew(agents=[agent], tasks=[task], process=Process.sequential, verbose=True, memory=False)
result = crew.kickoff()
output = result
print(f"crew.kickoff() output length: {len(output) if output else 0}")
print(f"crew.kickoff() output preview: {output[:500] if output else 'None'}")

# Test Case 2: Using task.execute_sync()
task.execute_sync(agent=agent)
output = task.output.raw if task.output else None
print(f"execute_sync() output length: {len(output) if output else 0}")
print(f"execute_sync() output preview: {output[:500] if output else 'None'}")

Both test cases should produce complete output without truncation.

Extra Tips

  • Ensure that the max_tokens parameter is set correctly for the LLM provider to avoid truncation.
  • Consider adding error handling to the Crew.kickoff() method to handle cases where output is truncated or incomplete.
  • Review the documentation for the LLM provider to ensure that you are using the correct parameters and settings for your use case.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

FAQ

Expected behavior

crew.kickoff() should return the complete LLM-generated output from the task, which is 2500-5700 characters of valid JSON.

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING

crewai - ✅(Solved) Fix [BUG]crew.kickoff() truncates LLM output but task.execute_sync() works correctly [2 pull requests, 2 comments, 2 participants]