Skip to content

codedeploy install/uninstall: TypeError (bytes vs str) crashes when agent service not found #10576

Description

@Adityaj0

Summary

aws deploy install / aws deploy uninstall (the on-premises CodeDeploy agent installer) crashes with an unhandled TypeError instead of gracefully handling the case where the codedeployagent/codedeploy-agent service does not exist yet — which is exactly the situation on a fresh host doing its first install.

Root cause

awscli/customizations/codedeploy/systems.py creates several subprocess.Popen(...) calls without text=True/universal_newlines=True:

process = subprocess.Popen(
    ['service', 'codedeploy-agent', 'stop'],
    stdout=subprocess.PIPE,
    stderr=subprocess.PIPE
)
(output, error) = process.communicate()
if process.returncode != 0 and params.not_found_msg not in error:
    raise RuntimeError(...)

Because text=True is omitted, process.communicate() returns bytes, but the code checks membership of a str literal (params.not_found_msg, or the not_found/"Running" literals in the Windows class) against that bytes object. In Python 3, "str" in b"bytes" raises TypeError: a bytes-like object is required, not 'str' — it does not evaluate to False.

Affected locations:

  • Windows.install (~L75): if process.returncode != 0 and not_found not in error:
  • Windows.install (~L108): if "Running" not in output:
  • Windows.uninstall (same pattern as install)
  • Linux._stop_agent (~L208, used by Ubuntu/RHEL install/uninstall): if process.returncode != 0 and params.not_found_msg not in error:

Reproduction

Verified by executing the real, unmodified Linux._stop_agent method against a stub service binary that reproduces the "service not registered yet" condition (exit code 1, stderr containing the expected "not found" message):

import sys
from awscli.customizations.codedeploy.systems import Linux

class Params(dict):
    def __getattr__(self, k):
        return self[k]

linux = Linux.__new__(Linux)
params = Params()
params['not_found_msg'] = 'codedeploy-agent: unrecognized service'

linux._stop_agent(params)

with a service script on PATH that does:

#!/bin/bash
echo "service: unrecognized service" 1>&2
exit 1

Result:

TypeError: a bytes-like object is required, not 'str'

instead of the intended graceful pass-through (or the documented RuntimeError when the failure is for a different reason).

Impact

This affects essentially every fresh aws deploy install and every aws deploy uninstall on Windows, Ubuntu, and RHEL on-premises instances — i.e. exactly the first-run scenario the not_found/not_found_msg check was written to tolerate. Instead of installing successfully or uninstalling cleanly, the command crashes with an unrelated TypeError traceback.

Suggested fix

Add text=True (or universal_newlines=True) to each subprocess.Popen(...) call in awscli/customizations/codedeploy/systems.py so communicate() returns str, matching what the existing string-membership checks assume.

Environment

Reviewed against the current aws-cli source. This is aws-cli-specific customization code (not vendored botocore).

Metadata

Metadata

Assignees

No one assigned

    Labels

    needs-triageThis issue or PR still needs to be triaged.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions