# Buggy code
def _raise_400_if_invalid_id(self, record_id):
    """Raise 400 if specified record id does not match the format excepted
    by storage backends.

    :raises: :class:`pyramid.httpexceptions.HTTPBadRequest`
    """
    if not self.model.id_generator.match(six.text_type(record_id)):
        error_details = {"location": "path", "description": "Invalid record id"}
        raise_invalid(self.request, **error_details)


# Traceback (BackendError)
2016-06-21 13:41:49,701 DEBUG [kinto.core.storage.postgresql.pool.QueuePoolWithMaxBacklog][waitress] Connection <connection object at 0x7f1f396ad6e0; dsn: 'dbname=postgres user=postgres password=xxxxxxxx host=localhost', closed: 0> checked out from pool
2016-06-21 13:41:49,711 ERROR [kinto.core.storage.postgresql.client][waitress] "POST  /v1/buckets/3f2e55d2-25ad-5fa9-3dcb-c0f29235627f/collections/foo/records" ? (? ms) (psycopg2.ProgrammingError) operator does not exist: text = integer
LINE 4:          WHERE id = 2
^
HINT:  No operator matches the given name and argument type(s). You might need to add explicit type casts.
[SQL: '\n        SELECT as_epoch(last_modified) AS last_modified, data\n          FROM records\n         WHERE id = %(object_id)s\n           AND parent_id = %(parent_id)s\n           AND collection_id = %(collection_id)s;\n        '] [parameters: {'parent_id': u'/buckets/3f2e55d2-25ad-5fa9-3dcb-c0f29235627f/collections/foo', 'object_id': 2, 'collection_id': 'record'}] agent=HTTPie/0.9.2 authn_type=basicauth collection_id=record collection_timestamp=1466530900543 errno=None lang=None uid=44ac0e1157457b4ff75a88b490cd735f73a27d5c8ac5b3fb4672d449969d88ea
2016-06-21 13:41:49,712 DEBUG [kinto.core.storage.postgresql.pool.QueuePoolWithMaxBacklog][waitress] Connection <connection object at 0x7f1f396ad6e0; dsn: 'dbname=postgres user=postgres password=xxxxxxxx host=localhost', closed: 0> being returned to pool
2016-06-21 13:41:49,712 DEBUG [kinto.core.storage.postgresql.pool.QueuePoolWithMaxBacklog][waitress] Connection <connection object at 0x7f1f396ad6e0; dsn: 'dbname=postgres user=postgres password=xxxxxxxx host=localhost', closed: 0> rollback-on-return, via agent
2016-06-21 13:41:49,713 CRITI [kinto.core.views.errors][waitress] "POST  /v1/buckets/3f2e55d2-25ad-5fa9-3dcb-c0f29235627f/collections/foo/records" ? (? ms) (psycopg2.ProgrammingError) operator does not exist: text = integer
LINE 4:          WHERE id = 2
^
HINT:  No operator matches the given name and argument type(s). You might need to add explicit type casts.
[SQL: '\n        SELECT as_epoch(last_modified) AS last_modified, data\n          FROM records\n         WHERE id = %(object_id)s\n           AND parent_id = %(parent_id)s\n           AND collection_id = %(collection_id)s;\n        '] [parameters: {'parent_id': u'/buckets/3f2e55d2-25ad-5fa9-3dcb-c0f29235627f/collections/foo', 'object_id': 2, 'collection_id': 'record'}] agent=HTTPie/0.9.2 authn_type=basicauth collection_id=record collection_timestamp=1466530900543 errno=None exception=Traceback (most recent call last):
File "/home/ethan/Jobs/Mozilla/kinto/.venv/lib/python2.7/site-packages/pyramid/tweens.py", line 22, in excview_tween
response = handler(request)
File "/home/ethan/Jobs/Mozilla/kinto/.venv/lib/python2.7/site-packages/pyramid_tm/__init__.py", line 101, in tm_tween
reraise(*exc_info)
File "/home/ethan/Jobs/Mozilla/kinto/.venv/lib/python2.7/site-packages/pyramid_tm/__init__.py", line 83, in tm_tween
response = handler(request)
File "/home/ethan/Jobs/Mozilla/kinto/.venv/lib/python2.7/site-packages/pyramid/router.py", line 158, in handle_request
view_name
File "/home/ethan/Jobs/Mozilla/kinto/.venv/lib/python2.7/site-packages/pyramid/view.py", line 547, in _call_view
response = view_callable(context, request)
File "/home/ethan/Jobs/Mozilla/kinto/.venv/lib/python2.7/site-packages/pyramid/viewderivers.py", line 413, in viewresult_to_response
result = view(context, request)
File "/home/ethan/Jobs/Mozilla/kinto/.venv/lib/python2.7/site-packages/pyramid/viewderivers.py", line 147, in _requestonly_view
response = view(request)
File "/home/ethan/Jobs/Mozilla/kinto/kinto/plugins/default_bucket/__init__.py", line 150, in default_bucket
response = request.invoke_subrequest(subrequest)
File "/home/ethan/Jobs/Mozilla/kinto/.venv/lib/python2.7/site-packages/pyramid/router.py", line 211, in invoke_subrequest
response = handle_request(request)
File "/home/ethan/Jobs/Mozilla/kinto/.venv/lib/python2.7/site-packages/pyramid/router.py", line 158, in handle_request
view_name
File "/home/ethan/Jobs/Mozilla/kinto/.venv/lib/python2.7/site-packages/pyramid/view.py", line 547, in _call_view
response = view_callable(context, request)
File "/home/ethan/Jobs/Mozilla/kinto/.venv/lib/python2.7/site-packages/pyramid/config/views.py", line 182, in __call__
return view(context, request)
File "/home/ethan/Jobs/Mozilla/kinto/.venv/lib/python2.7/site-packages/pyramid/viewderivers.py", line 393, in attr_view
return view(context, request)
File "/home/ethan/Jobs/Mozilla/kinto/.venv/lib/python2.7/site-packages/pyramid/viewderivers.py", line 371, in predicate_wrapper
return view(context, request)
File "/home/ethan/Jobs/Mozilla/kinto/.venv/lib/python2.7/site-packages/pyramid/viewderivers.py", line 302, in _secured_view
return view(context, request)
File "/home/ethan/Jobs/Mozilla/kinto/.venv/lib/python2.7/site-packages/pyramid/viewderivers.py", line 442, in rendered_view
result = view(context, request)
File "/home/ethan/Jobs/Mozilla/kinto/.venv/lib/python2.7/site-packages/pyramid/viewderivers.py", line 147, in _requestonly_view
response = view(request)
File "/home/ethan/Jobs/Mozilla/kinto/.venv/lib/python2.7/site-packages/cornice/service.py", line 571, in wrapper
response = view_()
File "/home/ethan/Jobs/Mozilla/kinto/kinto/core/resource/__init__.py", line 303, in collection_post
existing = self._get_record_or_404(_id)
File "/home/ethan/Jobs/Mozilla/kinto/kinto/core/resource/__init__.py", line 670, in _get_record_or_404
return self.model.get_record(record_id)
File "/home/ethan/Jobs/Mozilla/kinto/kinto/core/resource/model.py", line 274, in get_record
record = super(ShareableModel, self).get_record(record_id, parent_id)
File "/home/ethan/Jobs/Mozilla/kinto/kinto/core/resource/model.py", line 142, in get_record
auth=self.auth)
File "/home/ethan/Jobs/Mozilla/kinto/kinto/core/storage/postgresql/__init__.py", line 261, in get
existing = result.fetchone()
File "/usr/lib64/python2.7/contextlib.py", line 35, in __exit__
self.gen.throw(type, value, traceback)
File "/home/ethan/Jobs/Mozilla/kinto/kinto/core/storage/postgresql/client.py", line 53, in connect
raise exceptions.BackendError(original=e)
BackendError: ProgrammingError: (psycopg2.ProgrammingError) operator does not exist: text = integer
LINE 4:          WHERE id = 2
^
HINT:  No operator matches the given name and argument type(s). You might need to add explicit type casts.
[SQL: '\n        SELECT as_epoch(last_modified) AS last_modified, data\n          FROM records\n         WHERE id = %(object_id)s\n           AND parent_id = %(parent_id)s\n           AND collection_id = %(collection_id)s;\n        '] [parameters: {'parent_id': u'/buckets/3f2e55d2-25ad-5fa9-3dcb-c0f29235627f/collections/foo', 'object_id': 2, 'collection_id': 'record'}] lang=None uid=44ac0e1157457b4ff75a88b490cd735f73a27d5c8ac5b3fb4672d449969d88ea
2016-06-21 13:41:49,713 INFO  [kinto.core.initialization][waitress] "POST  /v1/buckets/3f2e55d2-25ad-5fa9-3dcb-c0f29235627f/collections/foo/records" 503 (13 ms) request.summary agent=HTTPie/0.9.2 authn_type=basicauth collection_id=record collection_timestamp=1466530900543 errno=201 lang=None time=2016-06-21T13:41:49 uid=44ac0e1157457b4ff75a88b490cd735f73a27d5c8ac5b3fb4672d449969d88ea

# Fixed code
def _raise_400_if_invalid_id(self, record_id):
    """Raise 400 if specified record id does not match the format excepted
    by storage backends.

    :raises: :class:`pyramid.httpexceptions.HTTPBadRequest`
    """
    is_string = isinstance(record_id, six.string_types)
    if not is_string or not self.model.id_generator.match(record_id):
        error_details = {"location": "path", "description": "Invalid record id"}
        raise_invalid(self.request, **error_details)