Skip to content

[BUG]: TypeError: not all arguments converted during string formatting #13211

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
AndyYaG opened this issue Apr 16, 2025 · 0 comments
Open

[BUG]: TypeError: not all arguments converted during string formatting #13211

AndyYaG opened this issue Apr 16, 2025 · 0 comments
Labels

Comments

@AndyYaG
Copy link

AndyYaG commented Apr 16, 2025

Tracer Version(s)

3.4.1

Python Version(s)

Python 3.12.0

Pip Version(s)

pip 23.2.1

Bug Report

String Formatting Issue in DDTelemetryLogHandler

Issue Summary

A TypeError: not all arguments converted during string formatting exception occurred in the DDTelemetryLogHandler.emit() method when attempting to format log messages using the % operator with record.msg and record.args:

self.telemetry_writer.add_error(1, record.msg % record.args, full_file_name, record.lineno)

This issue happened when I updated the following libraries:

  • Python 3.9.13 -> 3.12.0
  • Django 4.1.9 -> 5.2
  • ddtrace 2.12.2 -> 3.4.1

Root Cause Analysis

The error occurs because of a mismatch between format specifiers in record.msg and the arguments in record.args. This mismatch can happen in several scenarios:

  1. Tuple Handling: When record.args is already a tuple, direct application using % can cause errors because the tuple is not unpacked correctly.

  2. Format Specifier Mismatch: If there are more or fewer format specifiers (%s, %d, etc.) in the message than there are arguments provided.

  3. Missing Arguments: When a format specifier exists in the message, but no corresponding argument is provided.

  4. Non-Iterable Value: If record.args is a non-iterable value when multiple format specifiers exist in record.msg

  5. Arguments Mismatch: If there's a mismatch between the number of specifiers and provided arguments

  6. Unexpected type: If record.args is an unexpected type that causes issues with the formatting mechanism

Solution Implemented

The issue was resolved by replacing the direct formatting with the LogRecord.getMessage() method:

self.telemetry_writer.add_error(1, record.getMessage(), full_file_name, record.lineno)
def getMessage(self):
        """
        Return the message for this LogRecord.

        Return the message for this LogRecord after merging any user-supplied
        arguments with the message.
        """
        msg = str(self.msg)
        if self.args:
            msg = msg % self.args
        return msg

This method internally manages all string formatting edge cases and safely returns a properly formatted log message. If using Python 3.12, the getMessage method is already available in the standard logging package. However, a more robust solution should ensure consistent handling of these edge cases across different Python versions. I believe we can approach it with something like this:

try:
    iter(possibly_iterable)
except TypeError:
    # Handle non-iterable case
    iterable = [possibly_iterable]
else:
    # Handle iterable case
    iterable = possibly_iterable

Or could we implement a solution to maintain multiple versions for compatibility?

Reproduction Code

No response

Error Logs

local-gameserver | Traceback (most recent call last):
local-gameserver | File "/usr/local/lib/python3.12/threading.py", line 1052, in _bootstrap_inner
local-gameserver | self.run()
local-gameserver | File "/usr/local/lib/python3.12/threading.py", line 989, in run
local-gameserver | self._target(*self._args, **self._kwargs)
local-gameserver | File "/usr/local/lib/python3.12/site-packages/concurrent_log_handler/queue.py", line 54, in _monitor
local-gameserver | super()._monitor() # type: ignore[misc]
local-gameserver | ^^^^^^^^^^^^^^^^^^
local-gameserver | File "/usr/local/lib/python3.12/logging/handlers.py", line 1585, in _monitor
local-gameserver | self.handle(record)
local-gameserver | File "/usr/local/lib/python3.12/logging/handlers.py", line 1566, in handle
local-gameserver | handler.handle(record)
local-gameserver | File "/usr/local/lib/python3.12/logging/init.py", line 1028, in handle
local-gameserver | self.emit(record)
local-gameserver | File "/usr/local/lib/python3.12/site-packages/ddtrace/internal/telemetry/logging.py", line 24, in emit
local-gameserver | self.telemetry_writer.add_error(1, record.msg % record.args, full_file_name, record.lineno)
local-gameserver | ~~~~~~~~~~~^~~~~~~~~~~~~
local-gameserver | TypeError: not all arguments converted during string formatting

Libraries in Use

aiohappyeyeballs==2.6.1
aiohttp==3.11.16
aiosignal==1.3.2
amqp==5.3.1
anyio==4.9.0
asgiref==3.8.1
attrs==25.3.0
bcrypt==4.3.0
billiard==4.2.1
boto3==1.37.34
botocore==1.37.34
bytecode==0.16.2
cachetools==5.5.2
cbor2==5.6.5
celery==5.5.1
celery-redbeat==2.3.2
certifi==2025.1.31
cffi==1.17.1
charset-normalizer==3.4.1
click==8.1.8
click-didyoumean==0.3.1
click-plugins==1.1.1
click-repl==0.3.0
concurrent-log-handler==0.9.25
cookies==2.2.1
cryptography==44.0.2
datadog==0.51.0
ddtrace==3.4.1
decorator==5.2.1
defusedxml==0.7.1
Deprecated==1.2.18
distlib==0.3.9
Django==5.2
django-annoying==0.10.8
django-datetime-widget==0.9.3
django-extensions==4.1
django-ipware==7.0.1
django-jenkins==0.110.0
django-ratelimit3==1.0.1
django-redis==5.4.0
django-suit==0.2.28
django-tables2==2.7.5
django-uuidfield==0.5.0
envier==0.6.1
filelock==3.18.0
flatbuffers==25.2.10
flower==2.0.1
frozenlist==1.5.0
gevent==24.11.1
google-api-core==2.24.2
google-api-python-client==2.167.0
google-auth==2.39.0
google-auth-httplib2==0.2.0
google-cloud-core==2.4.3
google-cloud-storage==3.1.0
google-crc32c==1.7.1
google-resumable-media==2.7.2
googleapis-common-protos==1.70.0
greenlet==3.2.0
h11==0.14.0
h2==4.2.0
hiredis==3.1.0
hpack==4.1.0
httpcore==1.0.8
httplib2==0.22.0
httpx==0.28.1
humanize==4.12.2
hyperframe==6.1.0
idna==3.10
importlib_metadata==8.6.1
ipaddress==1.0.23
jmespath==1.0.1
kombu==5.5.2
lazy-object-proxy==1.10.0
leaderboard==3.7.3
lxml==5.3.2
maxminddb==2.6.3
mock==5.2.0
multidict==6.4.3
ndg-httpsclient==0.5.1
numpy==2.2.4
oauth2client==4.1.3
oauthlib==3.2.2
opentelemetry-api==1.32.1
pandas==2.2.3
platformdirs==4.3.7
portalocker==3.1.1
prometheus_client==0.21.1
prompt_toolkit==3.0.51
propcache==0.3.1
proto-plus==1.26.1
protobuf==6.30.2
pubnub==10.3.0
pyasn1==0.6.1
pyasn1_modules==0.4.2
pycparser==2.22
pycryptodome==3.22.0
pycryptodomex==3.22.0
PyJWT==2.10.1
pylibmc==1.6.3
pynamodb==6.0.2
pyOpenSSL==25.0.0
pyparsing==3.2.3
python-dateutil==2.9.0.post0
python-ipware==3.0.0
python-oauth2==1.1.1
python-redis-lock==4.0.0
python-social-auth==0.3.6
python3-openid==3.2.0
pytz==2025.2
qless-py==0.11.4
redis==5.2.1
requests==2.32.3
requests-oauthlib==2.0.0
responses==0.4.0
rsa==4.9
s3transfer==0.11.4
setproctitle==1.3.5
setuptools==29.0.1
simplejson==3.20.1
six==1.17.0
sniffio==1.3.1
social-auth-app-django==5.4.3
social-auth-core==4.5.6
South==1.0.2
sqlparse==0.5.3
tenacity==9.1.2
theine==0.5.0
theine_core==0.4.5
titan-sdk==3.0.9
tornado==6.4.2
typing_extensions==4.13.2
tzdata==2025.2
tzlocal==5.3.1
unittest-xml-reporting==3.2.0
uritemplate==4.1.1
urllib3==2.4.0
uwsgidecorators==1.1.0
vine==5.1.0
virtualenv==20.30.0
wcwidth==0.2.13
wheel==0.42.0
wrapt==1.17.2
xmltodict==0.14.2
yarl==1.19.0
zipp==3.21.0
zope.event==5.0
zope.interface==7.2

Operating System

Linux 6c8efc41b480 6.9.8-orbstack-00170-g7b4100b7ced4 #1 SMP Thu Jul 11 03:32:20 UTC 2024 aarch64 GNU/Linux

@AndyYaG AndyYaG added the bug label Apr 16, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant