router-for-me/CLIProxyAPI · error

Codex live media relay requires an SDP or JSON call request

Error message

Codex live media relay requires an SDP or JSON call request

What it means

dlopen failed to load the plugin shared library; the message embeds the plugin path and the platform dlerror string. This is the Unix dynamic loader rejecting the file before any plugin code runs — missing shared-object dependencies, wrong architecture, not a shared library at all, or loader permission/ELF issues.

Source

Thrown at internal/client/codex/live/live.go:696

		Session: session,
	}
	encoded, errMarshal := json.Marshal(payload)
	if errMarshal != nil {
		return nil, fmt.Errorf("failed to encode Codex live request: %w", errMarshal)
	}
	return encoded, nil
}

func callRequestSDP(body []byte, contentType string) (string, error) {
	mediaType, _, errMediaType := mime.ParseMediaType(contentType)
	if errMediaType == nil && (strings.EqualFold(mediaType, "application/sdp") || strings.EqualFold(mediaType, "text/plain")) {
		if strings.TrimSpace(string(body)) == "" {
			return "", errors.New("Codex live call request requires an SDP offer")
		}
		return string(body), nil
	}
	if errMediaType != nil || !strings.EqualFold(mediaType, "application/json") {
		return "", errors.New("Codex live media relay requires an SDP or JSON call request")
	}
	var payload struct {
		SDP string `json:"sdp"`
	}
	if errUnmarshal := json.Unmarshal(body, &payload); errUnmarshal != nil {
		return "", fmt.Errorf("failed to decode Codex live call request: %w", errUnmarshal)
	}
	if strings.TrimSpace(payload.SDP) == "" {
		return "", errors.New("Codex live call request requires an SDP offer")
	}
	return payload.SDP, nil
}

func replaceCallRequestSDP(body []byte, contentType, sdp string) ([]byte, string, error) {
	mediaType, _, errMediaType := mime.ParseMediaType(contentType)
	if errMediaType == nil && (strings.EqualFold(mediaType, "application/sdp") || strings.EqualFold(mediaType, "text/plain")) {
		encoded, errEncode := encodeCallRequest(sdp, nil)
		if errEncode != nil {

View on GitHub (pinned to 78f0c4079e)

Solutions

  1. Run ldd <plugin.so> on the target machine to list unresolved shared library dependencies and install/point LD_LIBRARY_PATH at them.
  2. Rebuild the plugin on/for the same OS+arch as the host (GOOS/GOOS targets, or -buildmode=c-shared with the matching toolchain).
  3. Verify the file is a valid shared object (file <plugin.so>) and not corrupted or a Windows DLL.
  4. Ensure the plugin directory is not mounted noexec.

Example fix

# before: plugin built on mac, deployed to linux
file plugin.so   # => Mach-O ... (wrong platform)

# after: rebuild for the host platform
GOOS=linux GOARCH=amd64 go build -buildmode=c-shared -o plugin.so ./plugin
Defensive patterns

Strategy: validation

Validate before calling

# preflight before enabling the plugin in config
file plugin.so        # expect: ELF ... shared object (matching arch)
ldd plugin.so         # expect: no 'not found' entries

Prevention

When it happens

Trigger: Plugin .so built for a different OS/arch than the host (e.g. darwin/arm64 dylib on linux/amd64); plugin linked against shared libraries absent from LD_LIBRARY_PATH; file corrupted or not an ELF shared object; noexec mount.

Common situations: Building plugins on a dev machine and deploying to a different distro/arch; CGO toolchain differences producing versioned symbol dependencies (glibc mismatches); plugins downloaded for the wrong platform; directory mounted noexec in containers.

Related errors


AI-assisted analysis of router-for-me/CLIProxyAPI@78f0c4079e (2026-08-15). Data as JSON: /api/errors/2d19d6aa45c33798. Report an issue: GitHub.