Skip to content

Conversation

Copy link
Contributor

Copilot AI commented Dec 18, 2025

The shim fails with ENXIO ("device not configured") when term.IsTerminal() reports stdin/stdout as TTYs but the underlying terminal device is closed, detached, or otherwise invalid—triggering when pty.Start() attempts PTY operations.

Changes

  • internal/execx/run.go: Added term.GetState() validation in IsTTY() to verify terminal is actually usable before attempting PTY operations. Falls back to pipe mode when state check fails.
  • internal/execx/run_test.go: Added test coverage for terminal state validation logic.
func IsTTY() bool {
    stdinFd := int(os.Stdin.Fd())
    stdoutFd := int(os.Stdout.Fd())
    
    if !term.IsTerminal(stdinFd) || !term.IsTerminal(stdoutFd) {
        return false
    }
    
    // Verify terminal is actually usable before attempting PTY operations
    if _, err := term.GetState(stdinFd); err != nil {
        return false
    }
    
    return true
}

This prevents PTY initialization failures while maintaining full PTY support for valid terminals.

Warning

Firewall rules blocked me from connecting to one or more addresses (expand for details)

I tried to connect to the following addresses, but was blocked by firewall rules:

  • version
    • Triggering command: /usr/bin/curl /usr/bin/curl version --64 tachttool -I EhXc9oXdH cfg share/ackchyually/shims/git --gdwarf-5 --64 -o share/ackchyually/shims/git -I kchyually/internal/eval/helpcount/helpcount.go kchyually/internal/eval/helpcount/scenarios.go /share/ackchyually/shims/git --gdwarf-5 --64 -o /share/ackchyually/shims/git (dns block)
    • Triggering command: /usr/bin/curl /usr/bin/curl version x86_64-linux-gnu-B ly/shims/git -W _.a eN7yY1GM7 4588/work/bin/exit0tool . /internal/app --64 4588/work/bin/exeval@example.com rtcf�� cN-YpiLin x64/src/crypto/internal/fips140/nistec/fiat/cast.go /share/ackchyually/shims/git --gdwarf-5 --64 -o /share/ackchyualEval (dns block)
    • Triggering command: /usr/bin/curl /usr/bin/curl version 6576090/b131/_x0-B tachttool 6576�� _.a /tmp/go-build2576576090/b131/ 4588/work/bin/exit0tool . --gdwarf2 --64 4588/work/bin/ex-b -plu�� /usr/libexec/gcc/x86_64-linux-gn--detach CZgK7V3yW ly/shims/git -plugin-opt=-pas/usr/bin/sh -plugin-opt=-pas-c -plugin-opt=-pasgit status ly/shims/git (dns block)

If you need me to access, download, or install something from one of these locations, you can either:

Original prompt

This section details on the original issue you should resolve

<issue_title>bug: "device not configured"</issue_title>
<issue_description>### ackchyually version

ackchyually version: v0.1.2 commit: 8b00ac5 built: 2025-12-15T17:24:43Z

OS

macOS

What happened?

~/src/TeamSpace-iOS users/engage/sdk/1.90.0 clean % git fetch origin
ackchyually: device not configured

Steps to reproduce

~/src/TeamSpace-iOS users/engage/sdk/1.90.0 clean % git fetch origin
ackchyually: device not configured

PTY / interactive impact

No response</issue_description>

<agent_instructions>Figure out what's going on with this and resolve the issue.</agent_instructions>

Comments on the Issue (you are @copilot in this section)


✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.

Copilot AI and others added 2 commits December 18, 2025 17:16
… PTY operations

Co-authored-by: joelklabo <264977+joelklabo@users.noreply.github.com>
Co-authored-by: joelklabo <264977+joelklabo@users.noreply.github.com>
Copilot AI changed the title [WIP] Fix device not configured error on macOS Fix "device not configured" error on macOS when terminal state is invalid Dec 18, 2025
Copilot AI requested a review from joelklabo December 18, 2025 17:21
@joelklabo joelklabo marked this pull request as ready for review December 18, 2025 20:44
@joelklabo joelklabo requested review from Copilot and removed request for joelklabo December 18, 2025 20:44
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR addresses the "device not configured" (ENXIO) error that occurs on macOS when the terminal state is invalid. The fix adds validation to ensure terminal file descriptors are actually usable before attempting PTY operations.

Key Changes:

  • Enhanced IsTTY() function to validate terminal state using term.GetState() in addition to checking if stdin/stdout are terminals
  • Added test coverage for terminal state validation and pipe fallback behavior

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.

File Description
internal/execx/run.go Enhanced IsTTY() with term.GetState() validation to detect invalid terminal states and gracefully fall back to pipe mode
internal/execx/run_test.go Added tests for terminal state validation and pipe fallback behavior

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

// If GetState fails, the terminal might be in an invalid state (closed/detached).
if _, err := term.GetState(stdinFd); err != nil {
return false
}
Copy link

Copilot AI Dec 18, 2025

Choose a reason for hiding this comment

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

The implementation only validates the state of stdin, but not stdout. Since the function checks that both stdin AND stdout are terminals (line 15), it should also verify that stdout's state can be retrieved. If stdout is a terminal but in an invalid state, this could still lead to PTY initialization failures.

Consider adding a similar state check for stdout to ensure both file descriptors are usable before attempting PTY operations.

Suggested change
}
}
if _, err := term.GetState(stdoutFd); err != nil {
return false
}

Copilot uses AI. Check for mistakes.
Comment on lines +10 to +31
func TestIsTTY_ValidatesTerminalState(t *testing.T) {
// This test verifies that IsTTY() not only checks if stdin/stdout are terminals,
// but also validates that we can actually get the terminal state.
// This prevents "device not configured" errors when terminals are in an invalid state.

// In a normal test environment, stdin/stdout are not terminals.
// So IsTTY should return false.
if IsTTY() {
t.Skip("Running in a TTY environment; can't test non-TTY behavior")
}

// Verify that if stdin is a terminal, we can get its state.
stdinFd := int(os.Stdin.Fd())
if term.IsTerminal(stdinFd) {
if _, err := term.GetState(stdinFd); err != nil {
// If we can't get the state, IsTTY should return false
if IsTTY() {
t.Error("IsTTY() returned true even though GetState failed")
}
}
}
}
Copy link

Copilot AI Dec 18, 2025

Choose a reason for hiding this comment

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

This test does not effectively validate the fix for the "device not configured" issue. The test logic on lines 17-30 has a problem: if IsTTY() returns false initially (line 17), the code will skip. Otherwise, it checks if stdin is a terminal and if GetState fails - but if GetState fails, IsTTY() would have already returned false, so line 26 would never execute the error condition.

The test doesn't simulate the actual problematic scenario where term.IsTerminal() returns true but term.GetState() fails (the invalid terminal state that causes ENXIO). Consider using a mock or creating a test that can actually trigger this condition, or alternatively, remove this test since the second test (TestRun_FallsBackToPipesWhenPTYUnavailable) already provides basic coverage for the fallback behavior.

Copilot uses AI. Check for mistakes.
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.

bug: "device not configured"

2 participants